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           // 提供了介绍和一个服务端发送到客户端的方法

原文地址:https://www.cnblogs.com/zuochanzi/p/13958039.html