zoukankan      html  css  js  c++  java
  • C#SignalR 做消息通知的调试纪要

    先说说这个SignalR    微软封装websocket 用作网页中前后端及时通信的框架.

    可以用作后台实时通知前端

    引用前辈的图

    这个框架里边的模式封装的挺有意思.当然也会有超出自己以前默认的想法的地方

    第一,客户端往服务器发送信息, 连接后,先要申请个代理,

     _hubProxy = _signalRConnection.CreateHubProxy(hubName);
     _hubProxy.Invoke("Send", txtUsername.Text, txtMessage.Text).Wait()
    然后上边才能用这个代理往服务器发送信息 .上边客户端往服务器发送信息的命令,里边的"Send" 是服务器上已经提前写好的send 方法,不是瞎写的.是服务器端的方法,不是客户端的啊

    服务器端的Send,在hub继承类中写,可以这么理解,客户端先连接服务器,然后申请了代理,通过代理可以调用服务器的send方法, 当然proxy下边介绍了是个json转译 ,对象转换.
    理解起来,就是客户端发了一串json ,跟服务器说,我要调用send 方法? 神马鬼逻辑...总之 使用
    _hubProxy.Invoke("Send", txtUsername.Text, txtMessage.Text).Wait()
    发送,服务器中Send就会收到传过来的 名字和信息,神奇吧
    下边是服务器端的接收代码,也就是客户端的发送代码 下边那行没注释掉, 注释掉也是没问题的.

    下边是客户端连接代码  
    myhub 
      string host = "http://localhost:8889"; 
                string hubName = "myhub";
    
                _signalRConnection = new HubConnection(host);
                _signalRConnection.StateChanged += HubConnection_StateChanged;
    
                _hubProxy = _signalRConnection.CreateHubProxy(hubName);
    
                // Register to the "broadcastMessage" callback method of the hub
                // This method is invoked by the hub
                _hubProxy.On<string, string>("sendMessage", (name, message) => OnMessageReceived(name, message) );

     里边有个hub,就像是集线器,客户端连接到服务器,然后再注册产生一个hub 名 

    _hubProxy.On<string, string>("sendMessage", (name, message) => OnMessageReceived(name, message) );
    注意sendMessage 这是注册到服务器hub 上,跟服务器说,你要给我发消息,需要用sendMessage 这个命令
    也就是服务器端 hubContext.Clients.All.sendMessage(id, title); //调用客户端的函数

    服务器端发送代码 客户端连接过来时会存一个id ,

    Clients.Client(mc.id).SendMessage("ID:" + connectionid, message + " 时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); 一直报错未初始化,下边的调通了,感觉像是发给全部的客户端

      /// <summary>
            /// 发送消息 2019年10月16日12:28:18  Dennyhui
            /// </summary>
            /// <param name="message"></param>
            public static void SendMsg(string id, string title, string message, string poptype)
            {
                //调用所有客户端的sendMessage方法(sendMessage有2个参数)  
                //Clients.All.SendMessage("测试");
                //Clients.All.broadcastMessage("测试");
                //Clients.All.notify("测试");
                var hubContext = GlobalHost.ConnectionManager.GetHubContext<myhub>();//此处的“ServerHub”需要和当前的类名一直
                hubContext.Clients.All.sendMessage(id, title); //用户调用客户端的函数 
                //Clients.All.sendMessage(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "测试");
            }

     以上实现了 两个winform 窗口  ,服务器与客户端的互通,一下是 

    BS  CS 混合模式, 也就是服务器是用winform实现, 客户端由html实现

    服务器端不变, html端只需要jquery

     这两个js 为必须 下边的在 c# winform 项目目录中packagesMicrosoft.AspNet.SignalR.JS.2.4.1contentScripts文件夹 中

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="jquery-3.0.0/jquery-3.0.0.js"></script>
    <link rel="stylesheet" href="css/layui.css">
    //<button class="layui-btn">查看消息<span class="layui-badge layui-bg-gray">1</span></button>
    
    <h2>signalR<label id="rstart"></label></h2>
    <div>
        当前在线人数:<label id="users"></label>
        <select id="userslist"></select>
        <label id="messageBox"></label>
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="发送" />
        <input type="button" id="stopsignalr" value="断开连接" />
        <input type="button" id="startsignalr" value="重新连接" />
    </div>
    
    <script src="SignalRJS/jquery.signalR-2.4.1.js"></script>
    
    <script src="http://localhost:8889/signalr/hubs"></script>
    <script>
    
    
        $.connection.hub.url = "http://localhost:8889/signalr";
        var chat = $.connection.myhub;
        chat.client.sendmessage = function(name, message)
        {
            //向页面添加消息
            $("#messageBox").append('<li><strong style="color:green">' + name + '</strong>:' + message + '</li>');
        }
        // 开始连接服务器
        var hubid = "";
        $.connection.hub.start().done(function ()
        {
            console.log("id"+$.connection.hub.id);
            hubid = $.connection.hub.id;
    
            $('#sendmessage').on('click', function() {
                //调用服务器端集线器的Send方法
                chat.server.send(hubid,$('#message').val());
                //清空输入框信息并获取焦点
                $("#message").val('').focus();
            });
        });
        $("#stopsignalr").click(function ()
        {
            $.connection.hub.stop(hubid);
        });
        $("#startsignalr").click(function ()
        {
            $.connection.hub.start();
        });
    
    
    
       /* $(document).ready(function () {
            console.log("a")
            //引用自动生成的集线器代理
            var chat = $.connection.mvcfhub;
            chat.client.status = function (status) {
                $("#rstart").text('');
                if (status)
                    $("#rstart").text('在线');
    
            }
            chat.client.getusers = function (userslist) {
                var selectlist = "";
                $("#users").text('');
                $("#users").append(userslist.length);
                $.each(userslist, function (index, name) {
                    selectlist += "<option value=" + userslist[index] + ">" + userslist[index] + "</option>";
                });
                $("#userslist").html("");
                $("#userslist").append(selectlist);
            }
    
            //定义服务器调用的客户端sendMessage来显示新消息
            chat.client.SendMessage = function (name, message) {
                //向页面添加消息
                $("#messageBox").append('<li><strong style="color:green">' + name + '</strong>:' + message + '</li>');
            }
            $.connection.hub.connectionSlow(function () {
                console.log("连接出问题了!");
            });
            /!*重新连接*!/
            //$.connection.hub.disconnected(function () {
            //    setTimeout(function () {
            //        $.connection.hub.start().done(function () {
            //            console.log("重新连接成功!")
            //        });
            //    }, 5000); // Restart connection after 5 seconds.
            //});
            // 开始连接服务器
            var hubid = "";
            $.connection.hub.start().done(function () {
                hubid = $.connection.hub.id;
                chat.server.userlist();
                $('#sendmessage').on('click', function () {
                    //调用服务器端集线器的Send方法
                    chat.server.sendone($('#message').val(), $("#userslist").val());
                    //清空输入框信息并获取焦点
                    $("#message").val('').focus();
                });
            });
            $("#stopsignalr").click(function () {
                $.connection.hub.stop(hubid);
            });
            $("#startsignalr").click(function () {
                $.connection.hub.start();
            });
        });
    */
    
    </script>

    最终还是挺兴奋,winform 跟网页端 竟然给互通了...

    引用:

    什么是signalR?
    
    Asp.net SignalR是微软为实现实时通信的一个类库。一般情况下,signalR会使用JavaScript的长轮询(long polling)的方式来实现客户端和服务器通信,随着Html5中WebSockets出现,SignalR也支持WebSockets通信。另外SignalR开发的程序不仅仅限制于宿主在IIS中,也可以宿主在任何应用程序,包括控制台,客户端程序和Windows服务等,另外还支持Mono,这意味着它可以实现跨平台部署在Linux环境下。
    
    signalR内部有两类对象:
    
    Http持久连接(Persisten Connection)对象:用来解决长时间连接的功能。还可以由客户端主动向服务器要求数据,而服务器端不需要实现太多细节,只需要处理PersistentConnection 内所提供的五个事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。
    Hub(集线器)对象:用来解决实时(realtime)信息交换的功能,服务端可以利用URL来注册一个或多个Hub,只要连接到这个Hub,就能与所有的客户端共享发送到服务器上的信息,同时服务端可以调用客户端的脚本。SignalR将整个信息的交换封装起来,客户端和服务器都是使用JSON来沟通的,在服务端声明的所有Hub信息,都会生成JavaScript输出到客户端,.NET则依赖Proxy来生成代理对象,而Proxy的内部则是将JSON转换成对象。
    
    SignalR将整个信息的交换封装起来,客户端和服务器都是使用JSON来沟通的,在服务端声明的所有Hub信息,都会生成JavaScript输出到客户端,.NET则依赖Proxy来生成代理对象,而Proxy的内部则是将JSON转换成对象。

    参考:https://www.cnblogs.com/daniel-niu/p/10536484.html#4734551  这个文章提供的是客户端与客户端之间的信息互通,没有服务器往客户端,当然代码要稍加改进,添加个发送便可

    https://blog.csdn.net/qq_23502409/article/details/102968078           // 提供了介绍和一个服务端发送到客户端的方法

  • 相关阅读:
    信号量Semaphore
    回环屏障CyclicBarrier
    线程同步器CountDownLatch
    vue 类似微信通讯录格式实现网易云音乐的歌手字母查询
    vue使用element的多个表格使用v-if切换,使用 :key="Math.random()" 后,表格排序出现问题
    vue使用pinyin的npm包将文字转为大写首字母字母
    vue中使用better-scroll滚动无效
    vue 移动端 图片懒加载 lazy
    表格配合keepalive缓存
    在保存数据之后,不知道什么时候清空数据,不如试试beforeRouteEnter
  • 原文地址:https://www.cnblogs.com/zuochanzi/p/13958039.html
Copyright © 2011-2022 走看看