1、概述
通过上篇史上最全面的SignalR系列教程-1、认识SignalR文章的介绍,我们对SignalR技术已经有了一个全面的了解。本篇开始就通过SignalR的典型应用的实现方式做介绍,例子虽然简单,但麻雀虽小五脏俱全。可以以此为基础,扩展到实际应用中。
SignalR 的实现机制与.NET WCF 或 Remoting 是相似的,都是使用远程代理来实现。在具体使用上,有两种不同通信模型:PersistentConnection 和 Hubs,其中 PersistentConnection 是实现了长时间的 Javascript 轮询(类似于 Comet),Hub 是用来解决实时信息交换问题,它是利用 Javascript 动态载入执行方法实现的。SignalR 将整个连接,信息交换过程封装得非常漂亮,客户端与服务器端全部使用 JSON 来交换数据。
通信模型 | 说明 |
---|---|
Persistent Connections | Persistent Connections表示一个发送单个,编组,广播信息的简单终结点。开发人员通过使用持久性连接Api,直接访问SignalR公开的底层通信协议。 |
Hubs | Hubs是基于连接Api的更高级别的通信管道,它允许客户端和服务器上彼此直接调用方法,SignalR能够很神奇地处理跨机器的调度,使得客户端和服务器端能够轻松调用在对方端上的方法。使用Hub还允许开发人员将强类型的参数传递给方法并且绑定模型 |
对于这两种方式的讨论,感兴趣的朋友可以移步:https://stackoverflow.com/questions/9280484/signalr-why-choose-hub-vs-persistent-connection
本篇主要介绍使用SignalR的永久连接类(Persistent Connections)的实现方式来实现消息推送(广播)功能,分别以Asp.NET MVC与控制台程序做实例演示。对于Hubs这种集线器的实现方式在下篇文章介绍。
2、SignalR的永久连接类Mvc实现
在ASP.NET MVC下实现SignalR的永久连接类非常的简单,只需简单4步就可以实现一个简单的群聊功能。
2.1、 创建ASP.NET Mvc项目
2.2、安装Nuget包
创建好项目后,要使用SignalR,需要先安装SignalR包,可以通过程序包管理控制台输入包安装命令进行安装。
Install-Package Microsoft.AspNet.SignalR
也可以使用界面方式,如下图所示。
2.3、增加SignalR服务
规划适当的SignalR服务文件存放的文件夹,如我们放在Connections文件夹中,在此文件夹右键选择新建项,我们选择SignalR Persistent Connection Class永久连接类项。
确定后,VS会自动给我们生成对应代码,如下:
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
namespace SignalRTestProj_1.Connections
{
public class ChatConnection : PersistentConnection
{
protected override Task OnConnected(IRequest request, string connectionId)
{
return Connection.Send(connectionId, "Welcome!");
}
protected override Task OnReceived(IRequest request, string connectionId, string data)
{
return Connection.Broadcast(data);
}
}
}
我们对代码做适当修改,让业务更人性化,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace SignalRTestProj_1.Connections
{
using Microsoft.AspNet.SignalR;
public class ChatConnection : PersistentConnection
{
private static int _connections = 0;
protected override Task OnConnected(IRequest request, string connectionId)
{
Interlocked.Increment(ref _connections);
//广播消息
Connection.Broadcast("新的连接加入,连接ID:" + connectionId + ",已有连接数:" + _connections);
return Connection.Send(connectionId, "双向连接成功,连接ID:" + connectionId);
}
/// <summary>
/// 连接断开
/// </summary>
protected override Task OnDisconnected(IRequest request, string connectionId, bool stopCalled)
{
Interlocked.Decrement(ref _connections);
return Connection.Broadcast(connectionId + "退出连接,已有连接数:" + _connections);
}
protected override Task OnReceived(IRequest request, string connectionId, string data)
{
var message = connectionId + "发送内容>>" + data;
return Connection.Broadcast(message);
}
}
}
2.4、启动路由注册
要使Signal启作用,我们必须启动路由注册,要让客户端能找到,我们使用Owin。如下图所示,我们添加一个Owin Start启动类。
using Microsoft.Owin;
using Owin;
using SignalRTestProj_1.Connections;
[assembly: OwinStartup(typeof(SignalRTestProj_1.App_Start.ChartStartup))]
namespace SignalRTestProj_1.App_Start
{
public class ChartStartup
{
public void Configuration(IAppBuilder app)
{
// 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888
// 配置上文实现的ChatConnections
app.MapSignalR<ChatConnection>("/Connections/ChatConnection");
}
}
}
至此,我们服务端就算搭建起来了,现在我们增加一个页面来实现调用。
2.5、前端界面处理
前端js实现消息广播,并实时记录
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>SignalR永久连接类 Demo</title>
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
</head>
<body>
<div>
<h1>SignalR永久连接类 Demo</h1>
<div>
<input type="text" id="msgContext" placeholder="请输入消息内容...." />
<button id="sendMessage" class="btn-primary">Send</button>
<ul id="messages"></ul>
</div>
<script>
var connection = $.connection("/Connections/ChatConnection");
connection.logging = true;
//客户端接收消息
connection.received(function (data) {
$('#messages').append('<li>' + data + '</li>');
});
//连接错误处理
connection.error(function (err) {
alert('与服务器连接报错:'+ err.message);
});
//连接成功
connection.start().done(function () {
$('#sendMessage').click(function () {
var val = $('#msgContext').val();
//向服务器端发送消息
connection.send(val);
});
});
</script>
</div>
</body>
</html>
OK,全面完成,F5运行看效果吧。
2.6、效果展示
3、控制台做SignalR服务端实现
除了Web实时应用之外,我们还可以用其他应用程序实现实时交互,如控制台。
只需要Install-Package Microsoft.AspNet.SignalR.Client命令,示例代码如下:
using Microsoft.AspNet.SignalR.Client;
using static System.Console;
namespace ClientWithSignalRDemo
{
class Program
{
static void Main(string[] args)
{
var connection = new Connection("http://localhost:65309/Connections/ChatConnection");
connection.Received += WriteLine;
connection.Start().Wait();
string line;
while ((line = ReadLine()) != null)
{
connection.Send(line).Wait();
}
}
}
}
4、代码下载
实例源码可以移步github下载,地址:https://github.com/yonghu86/SignalRTestProj