WinForm中 Asp.Net Signalr消息推送测试实例
初学Signalr,只了解一些皮毛,还需进一步学习。SignalR提供了一个简单的API,用于创建从服务器端.NET代码调用客户端浏览器(和其他客户端平台)中的JavaScript函数的服务器到客户端的远程过程调用(RPC)。SignalR还包括用于连接管理(例如,连接和断开连接事件)和分组连接的API。
上面描述都是官方文档中提出的,我的测试项目的主要需求如下:
1、建立一个SignalR服务,用于实时广播信息,供客户端使用。
2、建立一个客户端,功能是只给服务端进行推送,但不接收服务端的广播信息。
3、WinFrom程序或者ASP.NET WBE端客户端程序,用于接收和展示接收的信息。
基本的流程图:
等待
有了明确的需求,打开VS直接开干。
1、先建立一个SignalR服务端
创建一个SignalR广播服务只需三步
第一步:新建项目(WF或者控制台),NuGet下载SignalR动态库。
第二步:创建一个HUB类,用于客户端访问连接
// [HubName("MyHub"), Authorize] public class MyHub : Hub { public List<string> UserIdList1 { get; } = new List<string>(); /// <summary> /// 信息广播 /// </summary> /// <param name="identify">iot唯一标识</param> /// <param name="model">数据模型</param> [HubMethodName("Send")] public void Send(string identify, IOTModel model) { Clients.All.addMessage(identify, model); } /// <summary> /// 错误日志广播 /// </summary> /// <param name="identify">唯一标示</param> /// <param name="errMessage">错误信息</param> [HubMethodName("ErrSend")] public void Send(string identify, string errMessage) { Clients.All.addMessage(identify, errMessage); } /// <summary> /// 向首次连接的客户端返回实时数据,用于展示 /// </summary> /// <param name="identify"></param> /// <param name="list"></param> [HubMethodName("initSend")] public void Send(string identify, List<IOTModel> list) { Clients.All.initData(identify, list); } public override Task OnConnected() { UserIdList1.Add(Context.ConnectionId); //首次连接需要返回MongoDB中的最后一条记录供客户端展示 Send("IotList", ProdMongoDB.GetLastData()); return base.OnConnected(); } public override Task OnDisconnected(bool stopCalled) { UserIdList1.Remove(Context.ConnectionId); return base.OnDisconnected(stopCalled); } public override Task OnReconnected() { UserIdList1.Add(Context.ConnectionId); return base.OnReconnected(); } }
第三步:异步开启服务Signalr服务
开启服务之前需要设置服务的IP和端口
private IDisposable SignalR { get; set; } private string ServerURI = "http://" + ConfigurationManager.AppSettings["signalrAdress"]; private async void RunServer() { await Task.Run(() => StartServer()); } private void StartServer() { try { SignalR = WebApp.Start(ServerURI); } catch (TargetInvocationException) { SignalR.Dispose(); Console.WriteLine("Server failed to start. A server is already running on " + ServerURI); return; } }
2、建立一个客户端(WinForm 或者控制台程序),用于向服务端发送信息。
此客户端只负责给服务器发送信息,不接收服务器的广播信息,创建过程如下:
第一步:新建WF或控制台程序,添加动态库
第二步:创建连接对象,配置服务地址
//定义代理,广播服务连接相关 private static IHubProxy HubProxy { get; set; } private static readonly string ServerUrl = ConfigurationManager.AppSettings["signalrServer"]; //private static string _serverUrl =""; //定义一个连接对象 public static HubConnection Connection { get; set; }
第三步:异步连接服务端
//异步连接服务器 private async void ConnectAsync() { Connection = new HubConnection(ServerURI); Connection.Closed += Connection_Closed; ; HubProxy = Connection.CreateHubProxy("MyHub"); try { await Connection.Start(); } catch (HttpRequestException) { _logger.Error("Unable to connect to server: Start server before connecting clients."); return; } }
第四部:给服务端发送实时信息
HubProxy.Invoke("Send", "aaa", message);
发送信息中调用的Send是服务端HUB类中定义的发送方法,根据实际需求定义和使用方法。
3、建立一个WinForm客户端程序,用于接收服务端的广播信息
winform 客户端中定义连接服务端和上面2中的相同,不同之处是这个客户端只接收信息不发送信息。
跳过连接服务的部分
实时监听服务端的信息
Connection = new HubConnection(_serverUrl); Connection.Closed += Connection_Closed; HubProxy = Connection.CreateHubProxy("MyHub"); HubProxy.On<string, IOTModel>("AddMessage", RecvMsg);//接收实时信息 HubProxy.On<string, string>("addMessage", RecvMsg);//接收错误日志 HubProxy.On<string, List<IOTModel>>("initData", RecvMsg);//初始化监测数据
创建RecvMsg方法用于解析处理显示数据
private static void RecvMsg(string identifiy, string errMessage) { if (identifiy != "ErrorInfo") return; ErrorList.Add("错误信息:"+ errMessage + ",接收时间:" + DateTime.Now); //实时添加到richBox中 if (ErrorBox.InvokeRequired) { ErrorBox.Invoke((Action)(() => ErrorBox.AppendText("错误信息:" + errMessage + ",接收时间:" + DateTime.Now + " "))); return; } ErrorBox.AppendText("错误信息:" + errMessage + ",接收时间:" + DateTime.Now + " "); }
4、建立一个aps.net Web端客户端,和WinForm一样接收服务器广播信息。
建立web端客户端也比较简单,具体如下:
第一步:新建asp.net web应用程序,获取动态程序包
所需的js文件如上。
第二步:新建html 页面,编写脚本代码接收广播信息。
<script src="Scripts/jquery-3.0.0.js"></script> <script src="Scripts/jquery.signalR-2.2.2.js"></script> <script src="http://172.30.16.165:805/signalr/hubs"></script>
$(function() { //配置hub服务器的地址 $.connection.hub.url = "http://localhost:888/signalr"; //声明一个hub的代理,此处的MyHub为服务器端配置的Hub名称 var proxy = $.connection.myHub; //定义函数,接收服务广播,addMessage为服务端定义的客户端接收的方法 proxy.client.addMessage = function(name, message) { //对接收到的数据进行解析 if (name === "FYIot") { var html = "<tr><td>" + message.ConfigCode + "</td>"; html += "<td>" + message.ConfigValue + "</td>"; html += "<td>" + moment(message.SaveDate).format("YYYY-MM-DD HH:mm:ss") + "</td></tr>"; $("#sigBody").append(html); } } //连接服务 $.connection.hub.start().done(); $("#tableDiv").slimScroll({ height: 500 }); });
<div style="text-align: center"> <h3>实时数据</h3> </div> <div style=" 100%; padding: 20px;" id="tableDiv"> <table class="table table-bordered table-hover"> <thead> <tr> <th width="50%">监测项编号</th> <th width="20%">监测值</th> <th width="30%">监测时间</th> </tr> </thead> <tbody id="sigBody"> <tr> </tr> </tbody> </table> </div>