C# websocket的使用

2023-11-06

        实现背景:有两个设备(A跟B两个冰箱,两者都装有app),现在需要在A上面控制B进行开门。A需要调用服务器接口,然后服务器发送消息控制B开门;此处记录下服务器端实现过程。

    1,包使用的Fleck,直接去nuget里下载安装即可。

     2,【这一步可忽略不是重点】app端定死了只能是http的请求,由于各种原因(不做赘述),我们这边只能加了一个路由来重定向一下。在Global的Application_Start方法中加代码

#region 自定义路由
        //扩展自定义路由(app请求的地址格式都是 app/xxx/这种)(项目是aps.net)
        var defaults = new System.Web.Routing.RouteValueDictionary { { "Controller", "*" }, { "Action", "*" } };
        System.Web.Routing.RouteTable.Routes.MapPageRoute("CongGuiRoute", "app/{Controller}/{Action}", "~/CongGui.aspx", true, defaults);//defaults可为null
        //RouteConfig.RegisterRoutes(System.Web.Routing.RouteTable.Routes);//官方aspx路由规则
        #endregion




 //websocket,这是为了启动socket,对后面有用
            HS.Common.FleckHelper fleckHelper =  HS.Common.FleckHelper.GetFleckHelper();
            fleckHelper.StartUp();

2,创建FleckHelper帮助类(里面一些代码都没用到,用到时候再研究研究),里面的日志LogDBHelper类就不提供了,自己记录下就行了。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using Fleck;

namespace HS.Common
{
    public class FleckHelper
    {
        /*客户端保活关键词*/
        private static string FLAG = "KeepAlive";
        /*服务器返回的保活关键字*/
        private static string RETURN_FLAG = "rKeepAlive";
        //socket链接池
        private static Dictionary<string,  IWebSocketConnection> socketsPool;
        //sockets链接地址
        private static Dictionary<string, string> socketsAddress;
        //websocket服务对象
        private WebSocketServer server;
        //监控端口
        private string pointAddress;
        //单例模式锁对象
        private static object lockObj = new object();
        private static FleckHelper fleckHelper = null;


        private FleckHelper()
        {
            socketsPool = new Dictionary<string,IWebSocketConnection>();
            socketsAddress = new Dictionary<string, string>();
            pointAddress = ConfigurationManager.AppSettings["FleckWebSocketPoint"];
            server = new WebSocketServer(pointAddress);
        }

        /// <summary>
        /// 单例模式
        /// </summary>
        /// <returns></returns>
        public static FleckHelper GetFleckHelper()
        {
            if (fleckHelper == null)
            {
                lock (lockObj)
                {
                    if (fleckHelper == null)
                    {
                        fleckHelper = new FleckHelper();
                    }
                }
            }
            return fleckHelper;
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public void Initialization()
        {
            socketsPool = new Dictionary<string,  IWebSocketConnection>();
            socketsAddress = new Dictionary<string, string>();
            pointAddress = ConfigurationManager.AppSettings["FleckWebSocketPoint"];
            server = new WebSocketServer(pointAddress);
        }
        
        /// <summary>
        /// 启动
        /// </summary>
        public void StartUp() {
            //出错后进行重启
            server.RestartAfterListenError = true;
            //开始监听
            server.Start(socket =>
            {
                socket.OnOpen = () =>   //连接建立事件
                {
                    //获取客户端标识
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    LogDBHelper.WriteOperatDiary("websocket", clientUrl + "建立websocket链接");
                };
                socket.OnClose = () =>  //连接关闭事件
                {
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    LogDBHelper.WriteOperatDiary("websocket", socketsAddress[clientUrl] + "断开websocket链接,地址" + clientUrl);
                };
                socket.OnMessage = message =>  //接受客户端消息事件
                {
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    //心跳消息
                    if (FLAG == message)
                    {
                        socket.Send(RETURN_FLAG);
                    }
                    else
                    {
                        lock (socketsPool)
                        {
                            socketsPool[message] = socket;
                        }
                        lock (socketsAddress)
                        {
                            socketsAddress[clientUrl] = message;
                        }
                        LogDBHelper.WriteOperatDiary("websocket", message + "收到信息" + message + "地址" + clientUrl);
                    }
                };
            });
        }

        /// <summary>
        /// 向客户端发送消息
        /// </summary>
        /// <param name="clientID">客户端标志</param>
        /// <param name="message">信息</param>
        public void SendMessage(string clientID, string message)
        {
            lock (socketsPool)
            {
                IWebSocketConnection socket = null;
                socketsPool.TryGetValue(clientID, out socket);
                if (socket == null)
                {
                    LogDBHelper.WriteErrorDiarylog("websocket", "websocket链接不存在!"+ clientID);
                    throw new Exception("websocket链接不存在!");

                }
                else
                {
                    socketsPool[clientID].Send(message);
                    LogDBHelper.WriteOperatDiary("websocket", clientID + "发送信息" + message);
                }
            }
        }

        /// <summary>
        /// 检查一个客户端标志是否有对应链接
        /// </summary>
        /// <param name="clientID">客户端标志</param>
        /// <returns></returns>
        public bool Exist(string clientID)
        {
            IWebSocketConnection socket = null;
            lock (socketsPool)
            {
                socketsPool.TryGetValue(clientID, out socket);
                if (socket != null)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// 关闭所有链接
        /// </summary>
        public void Close()
        {
            foreach (var item in socketsPool.Values)
            {
                if (item != null)
                {
                    item.Close();
                }
            }
        }
    }
}

3,调用代码:CongGui.appx.cs

using HS.Business;
using HS.Business.Cooperation;
using HS.Common;
using HS.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class app_CongGui : System.Web.UI.Page
{

     
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Clear();
        Response.ContentType = "application/json";
        Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
        string result = "";
//通过Global路由过来的请求
        string Controller = Page.RouteData.Values["Controller"] == null ? null : Page.RouteData.Values["Controller"].ToString();
        string Action = Page.RouteData.Values["Action"] == null ? null : Page.RouteData.Values["Action"].ToString();
        LogDBHelper.WriteServiceDiaryLog("CongGui", "从柜接口调用:" + Controller + "|" + Action);
        if (Controller == "icebox" && Action == "openDoor")
        {
            result = openDoor();
        }
         

        Response.Write(result);
        Response.End();

    }
    /// <summary>
    /// 主冰箱控制从冰箱开门 (大冰箱)
    /// </summary>
    /// <returns></returns>
    private string openDoor()
    {
        try
        {
            string iceBoxId = Context.Request["iceBoxId"].ToString();
            LogDBHelper.WriteServiceDiaryLog("openDoor", iceBoxId + "主冰箱控制从冰箱开门");
            if (string.IsNullOrEmpty(iceBoxId))
            {
                LogDBHelper.WriteErrorDiarylog("openDoor", "冰箱信息错误");
                return "冰箱信息错误!";
            }
            using (AP_Equ_IceBoxBB iceBoxBB = new AP_Equ_IceBoxBB())
            {
                var iceBox = iceBoxBB.GetModel(Convert.ToInt32(iceBoxId));
                if (iceBox == null)
                {
                    LogDBHelper.WriteErrorDiarylog("openDoor", "未找到冰箱信息");
                    return "未找到冰箱信息!";
                }
                using (DV_CompanyBB companyBB = new DV_CompanyBB())
                {
                    var company = companyBB.GetModelByCompanyId(iceBox.corpId);
                    if (company == null)
                    {
                        LogDBHelper.WriteErrorDiarylog("openDoor", "冰箱关联企业信息错误");
                        return "冰箱关联企业信息错误!";
                    }
                    //websocket发送开门信息
                    var message = new JObject();
                    message["hospitalcode"] = company.companyNo;
                    message["iceboxNo"] = iceBox.iceBoxNo;
                    message["machineCode"] = iceBox.controlBoardCode;
                    message["boxNo"] = "";
                    message["type"] = 5;
                    message["description"] = "";
                    message["data"] = null;
                    FleckHelper fleckHelper = FleckHelper.GetFleckHelper();
                    fleckHelper.SendMessage(iceBox.controlBoardCode, message.ToString());
                    //创建开锁记录
                    using (AP_OP_IceBoxLockListBB iceboxLockBB = new AP_OP_IceBoxLockListBB())
                    {
                        AP_OP_IceBoxLockListData iceboxLock = new AP_OP_IceBoxLockListData();
                        iceboxLock.iceBoxId = iceBox.id;
                        iceboxLock.freezeAreaId = 0;
                        iceboxLock.dt = DateTime.Now.ToString();
                        iceboxLock.lockState = "主冰箱控制从冰箱开门";
                        iceboxLockBB.AddRecord(iceboxLock);
                    }
                    return @"{""Desc"":""获取成功"",""Type"":0,""Code"":""0000""}";
                }
            }
        }
        catch (Exception e)
        {
            return e.Message;
        }
    }
}

4,写在最后:这是第一次用,所以代码理解上可能偏差地方,欢迎各位指出错误以更好的更正。这里仅仅是做一个记录,方便以后翻阅。还可以看看这篇帖子网页端是如何实现的https://blog.csdn.net/weixin_46867655/article/details/106799674

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# websocket的使用 的相关文章

  • ASP.NET Core/MVC 6 ViewModel 中的依赖注入 (DI)

    我使用构造函数注入在控制器中成功使用了 ASP NET 5 MVC 6 DI 我现在有一个场景 我希望我的视图模型在实现 IValidatableObject 时在 Validate 方法中使用服务 ViewModel 中的构造函数注入不起
  • 模式弹出窗口上的按钮单击事件,在网格视图内未触发

    我遇到以下问题 场景 我有一个 asp 网格 其中有一些绑定到数据的列 最后一列已转换为模板字段 在这个模板字段中有一个按钮 上面附加了一个模式弹出扩展器 该字段中隐藏着一个模式弹出窗口 此模式弹出窗口用于添加新帐户 它包含 2 个文本框
  • 在 IIS7 中托管 ASP.NET 会导致访问被拒绝?

    我在 IIS7 中设置了一个使用 NET Framework 4 0 由 NetworkService 运行 的应用程序 但在浏览该网站时我得到以下信息 访问被拒绝 描述 访问服务此请求所需的资源时发生错误 您可能无权查看所请求的资源 错误
  • "/>

    Error 5 expected Css test css gt gt 我需要给吗 在这里 因为我的解决方案仍然无法正常工作 它开始给出一些其他错误 您需要添加一个等号 如下所示 Css test css gt gt 解释 块将整个语句或块
  • pubxml Web 发布工具事件生命周期

    我正在使用 Visual Studio 2012 中的 Web 发布工具发布到文件系统 我了解到我可以打开 Properties 文件夹中的 pubxml 来执行更高级的操作 我想要做的是在发布任务结束时运行命令行应用程序 我通常会在自定义
  • 如何获取 Visual Studio 的“发布”功能以包含生成后事件中的文件?

    我目前正在尝试使用 Visual Studio 2010 发布 和 MSDeploy 功能来处理我的 Web 部署需求 但在根据我的构建配置自定义包方面遇到了障碍 我在 32 位环境中开发 但需要为 64 位环境创建发布包 因此在 发布 配
  • 从另一个项目/dll 引用的 Asp.NET 用户控件具有 NULL 属性

    试图将一个常用的自定义控件移到一个新的类库中 也尝试了一个新的web项目 以便其他项目可以使用它 但是在另一个项目中使用时它的属性始终为NULL 不幸的是 搜索类似的问题并不能帮助解决我的问题 我将 web base config 中的新控
  • asp.net/jQuery:使用 jQuery 将数据发布到弹出窗口 [IE]

    我正在尝试在 asp net 应用程序中使用 jQuery 将数据发布到弹出窗口 如果弹出窗口打开 我会收到三个错误 第一个错误是 Errror the value of the property is null or undefined
  • ASP.NET 项目在移动到另一台计算机时抛出 HTTP 错误 500.19

    我将一个 3 层 ASP NET 项目从运行 Visual Studio 2010 的系统复制到也运行 Visual Studio 2010 的系统 当我右键单击并选择浏览器中位于 UI 层下的文件夹内的文件上的视图时 我得到错误 HTTP
  • 无法使用 dataformatstring 格式化日期时间

    由于某种原因 我无法在网格视图中格式化日期文本
  • mvc 2中的图像上传和预览

    我正在通过转换 asp net 网站来学习 mvc 2 在我的页面中 我必须上传图像并显示图像的预览 下面给出了我的 asp net 页面的屏幕截图 我将模型创建为 public class Contest public int conte
  • 了解 ASP.NET 应用程序文件夹

    ASP NET 中的应用程序文件夹用于存储对运行网站至关重要的各种元素 我想更深入地了解这些文件夹 特别是文件夹的可访问性 根据有关的文章ASP NET 网站布局 http msdn microsoft com en us library
  • index.g.cshtml 在哪里

    我正在尝试完成本教程 但是 通常 当我构建解决方案时 我会得到一个CS0234错误指出文件中缺少命名空间Index g cshtml cd 但是这个文件存在于哪里呢 我努力了 所有构建 清理 重建解决方案选项 我已重新启动 Visual S
  • 使用 ITextsharp 将 Html 导出为 PDF

    我已经尝试了下面的代码 我也遇到了错误 我正在使用最新的 DLL String strSelectUserListBuilder h1 My First Heading h1 p My first paragraph p String ht
  • 如何使用 Web 套接字和 Angular CLI 设置代理

    我有一个使用 Angular CLI 构建的简单 Web 应用程序 我希望它使用网络套接字与后端通信 我已经编写了后端 并使用一个简单的 index html 页面进行了测试 服务器可以在套接字上发送和接收该页面 在我的 angular c
  • 如何找到 IIS 在负载/性能测试期间模拟的平均并发用户数?

    我正在使用 JMeter 进行负载测试 我正在练习通过简单地增加我的分布式 JMeter 测试用例中的线程数并启动测试来查找我们的网络服务器可以处理的最大并发线程 用户 数量 然后 我突然意识到 虽然 MAX 数字可能有用 但REAL我的网
  • 如何根据 ASP.NET VNEXT MVC6 中给出的路径进行虚拟路由/重定向?

    我有一个网站 它在不同的路径上公开多个 API 每个 API 由特定于应用程序部分的控制器处理 例如example com Api Controller Action param1 stuff 其中控制器发生变化 但操作保持相当一致 我有几
  • 如何在 Asp.Net 页面上的一处处理所有错误/消息?

    我在这里寻找一些指导 在我的网站上 我将内容放入 Web 用户控件中 例如 我将有一个新闻项控件 一个文章控件 一个联系表单控件 这些将出现在我网站上的各个位置 我正在寻找一种方法 让这些控件将消息传递到它们所在的页面 我不想将它们紧密结合
  • Microsoft.Extensions.Caching.Redis 选择与 db0 不同的数据库

    一个关于了解使用哪个redis数据库以及如何配置它的问题 我有一个默认值ASP NET Core Web 应用程序和默认配置的本地redis服务器 含15个数据库 通过包管理控制台我已经安装了 Install Package Microso
  • 如何从 Web API 应用程序返回 PDF

    我有一个在服务器上运行的 Web API 项目 它应该从两种不同类型的源返回 PDF 实际的可移植文档文件 PDF 和存储在数据库中的 base64 字符串 我遇到的问题是将文档发送回客户端 MVC 应用程序 剩下的部分是关于所发生的一切以

随机推荐

  • VUE之Vxe-table动态生成多级表头及后端返回数据的处理

    需求 1 第一列为正常列 2 第二列开始为动态生成列 根据接口返回数据生成 3 最后一列为编辑列 步骤 写入动态html模板
  • 接口响应优化方案

    最近收到客户反映系统卡顿严重 然后让他截图看了下 最长响应时长居然高达16s 其他3s 4s的接口一大堆 简直是恐怖 简单来说 这个耗时16s的接口其实是统计一张历史数据表里的数据 这张表大概有三百多万条数据 日增长1万左右 因为客户要求最
  • C++(10)——友元

    友元 采用类的机制后实现了数据的隐藏与封装 类的数据成员一般定义为私有成员 成员函数一般定义为公有的 依此提供类与外界间的通信接口 但是 有时需要定义一些函数 这些函数不是类的一部分 但又需要频繁地访问类的数据成员 这时可以将这些函数定义为
  • xss漏洞简单案例

    目录 一 function render input return input 二 function render input return input 编辑 三 function render input return 四 functio
  • 测试老鸟常用的自动化测试工具有哪些?

    目录 一 自动化测试工具的类型 二 自动化测试工具有哪些 1 Selenium 2 Appium 3 Jmeter 4 Postman 5 SoapUI 6 Monkey 7 Robot Framework 8 QTP 9 LoadRunn
  • JS实现去除一个字符串中的所有标点和空格

    这是今天做练习的时候碰到的 有两种办法 一是先将要处理的字符串分割成数组 再用filter滤去数组中的标点和空格 filter对于回调函数返回true的项会保留在数组中 返回false的会被滤出数组 最后再把数组转成字符串 下面是实现方法
  • lol韩服服务器满了显示什么意思,LOL韩服再次回收超级账号,“rank分出现问题,针对LPL的选手吗”...

    前言 S11赛季的比赛正在如火如荼地进行中 相信绝大多数的玩家都关注了 最近一段时间的春季赛 lpl赛区和lck赛区的整体状态是非常不错的 因为今年msi在冰岛举办 所以很多的赛区都希望能够拿下这一次的冠军 如果不出意外的话 dwg战队应该
  • 关于AJAX请求服务器后缓存数据,造成没有及时刷新的问题

    最近在做项目的时候 使用了ajax去请求服务器的数据 刚开始还可以 我测试一切运行正常 我不是专业的测试人员哈 所以还是有些问题没有测出来哈 后来ajax请求的数据变化了 但是页面数据没有变 依然是第一次的数据 这个问题害我整了好大半天啊
  • My Fifteenth Page - 快乐数 - By Nicolas

    今天小尼写的这篇page针对的是leetcode上的202 快乐数所写的 首先小尼先简单介绍一下这道题 就是给定一正整数 然后每一次将该数的每一位都平方再相加得到一个新的数据 我们不断的反腐操作 最后如果这个数经过多次操作后返回到了原来的这
  • 戴尔笔记本开机logo进度条时间长的解决办法

    戴尔笔记本开机 出现进度条 需要等30s才出现系统界面 这种问题的一个原因是 BOOT List option 选项选了UEFI 将此选项设置为Legacy 进度条瞬间几秒钟跳过 亲测有效 系统是win10
  • 静态分析领域中弱点、不足、缺陷、故障等概念之间的关系

    在CWE范畴内 讨论的核心内容是 弱点 及 不足 而在软件静态分析范畴内 研究的核心内容是 缺陷 及 故障 CWE已经越来越多的被静态分析用于重要参照标准 因此有必要将这几个关键概念之间的关系梳理清楚 弱点 Weakness 定义 CWE中
  • 完美解决 Treating Unicode character as whitespace的问题

    在我们 copy 一些文本到 Xcode 里面的时候会有 Treating Unicode character as whitespace 的警告 此时认真检查你 copy 的文本部分 回车 空格是否有问题 当然一般检查不出来 如果 直接删
  • 概率论【合集】--猴博士爱讲课

    重点章节 条件概率 期望等等 第一课 随机事件和概率 1 6 无放回类题目 一次摸多个 例 1 盒子里有 3 绿 4 红共
  • 外网访问内网机器中的VMware虚拟机服务问题排查

    场景 家里的电脑 win10 搭了个开发环境 并安装了VMware的linux虚拟机 在虚拟机中通过docker部署了几个服务 希望能在公司访问家里的服务器 问题 内网访问虚拟机服务成功 外网访问失败 vm虚拟机通过桥接连接外网 固定ip
  • jQuery基本介绍和 DOM 对象互相转换

    文章目录 jQuery基本介绍和 DOM 对象互相转换 基本介绍 jQuery 的原理示意图 JQuery 基本开发步骤 说明 jQuery简单示例 jQuery 对象和 DOM 对象 什么是 jQuery 对象 DOM 对象转成 jQue
  • android 后台服务长时间运行---解决方案

    android 后台服务启动方式 第一种 Activity界面通过Intent启动相关service 等价于 Timer定时器 TimerTask定时任务 第二种 Activity界面通过发生广播启动相关service 等价于 AlarmM
  • java 数据脱敏工具类

    import org apache commons lang3 StringUtils p 脱敏工具 p author ocean version 1 0 0 date 2023 5 4 14 51 public class Encrypt
  • 灰灰-309-射击比赛

    本题目给出的射击比赛的规则非常简单 谁打的弹洞距离靶心最近 谁就是冠军 谁差得最远 谁就是菜鸟 本题给出一系列弹洞的平面坐标 x y 请你编写程序找出冠军和菜鸟 我们假设靶心在原点 0 0 输入格式 输入在第一行中给出一个正整数 N 10
  • Redis 7 第六讲 主从模式(replica)架构篇

    此篇开始进入架构篇范围 艸 理论 即主从复制 master以写为主 Slave以读为主 当master数据变化的时候 自动将新的数据异步同步到其它slave数据库 使用场景 读写分离 容灾备份 数据备份 水平扩容 主从架构 演示案例 注 m
  • C# websocket的使用

    实现背景 有两个设备 A跟B两个冰箱 两者都装有app 现在需要在A上面控制B进行开门 A需要调用服务器接口 然后服务器发送消息控制B开门 此处记录下服务器端实现过程 1 包使用的Fleck 直接去nuget里下载安装即可 2 这一步可忽略