Asp.net SignalR
一、介绍
SignalR对websocket、SSE、长连接、forever frame进行封装。
websocket(html5):ws协议,这个协议基于tcp的。也就是说和http没有关系(兼容性不好)
SSE:客户端订阅服务器的一个事件,然后方便通过这个事件推送到客户端。 server => client
长链接:保持一次链接的时间,例如保持一个链接5s
forever frame:在body中藏一个iframe,那么这个iframe和server是一个永久链接,如果server来数据,通过这个链接推送到client
二、PersistentConnection
1,参数
《1》 request: 获取一些链接中的附加信息,request.querystring
request.cookie
request是一个katana的包装类。
singlaR 的request 其实是asp.net 中的 Request的子集。
《2》 connectionId 这个参数就是 客户端连接到服务器的唯一标识。。。也就说这个标识标识了客户端。本质上来说,和SessionID是一个性质。 【GUID】
2,demo
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(WebApplication1.Startup1))] namespace WebApplication1 { public class Startup1 { public void Configuration(IAppBuilder app) { // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888 app.MapSignalRStartup1("/connection"); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Web; using Microsoft.AspNet.SignalR; namespace WebApplication1 { public class MyConnection1 : PersistentConnection { //js调用 start 触发 protected override Task OnConnected(IRequest request, string connectionId) { return Connection.Send(connectionId, "Welcome!"); } //js 调用send触发 protected override Task OnReceived(IRequest request, string connectionId, string data) { return Connection.Broadcast(data); } //关闭连接(或者浏览器窗口)触发 protected override Task OnDisconnected(IRequest request, string connectionId, bool stopCalled) { return base.OnDisconnected(request, connectionId, stopCalled); } } }MyConnection1
"utf-8" />html
二、group(建简易聊天室)
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(WebApplication1.Startup1))] namespace WebApplication1 { public class Startup1 { public void Configuration(IAppBuilder app) { // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888 app.MapSignalRStartup1("/connection"); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Web; using Microsoft.AspNet.SignalR; namespace WebApplication1 { public class MyConnection1 : PersistentConnection { private const string DEFAULT = "default"; //js调用 start 触发 protected override Task OnConnected(IRequest request, string connectionId) { this.Groups.Add(connectionId, DEFAULT); //excludeConnectionIds:排除通知的connectionId。在default组中,除了自己,其他人都能收到信息 return this.Groups.Send(DEFAULT, connectionId + "进入房间", connectionId); } //js 调用send触发 protected override Task OnReceived(IRequest request, string connectionId, string data) { //excludeConnectionIds:排除通知的connectionId。在default组中,除了自己,其他人都能收到信息 return this.Groups.Send(DEFAULT, connectionId + ":" + data, connectionId); } //关闭连接(或者浏览器窗口)触发 protected override Task OnDisconnected(IRequest request, string connectionId, bool stopCalled) { return base.OnDisconnected(request, connectionId, stopCalled); } } }MyConnection1
"utf-8" />html"text" id="txt" /> "button" id="send" value="发送"/> "context">
案例下载:https://pan.baidu.com/s/1YJN-bwertKNQc2O5JHlQgg
三、Hub
1,js调用直接后端方法、后端直接调用js方法
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(WebApplication1.Startup1))] namespace WebApplication1 { public class Startup1 { public void Configuration(IAppBuilder app) { // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888 app.MapSignalR(); } } }Startup1
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.AspNet.SignalR; namespace WebApplication1 { public class MyHub : Hub { public void Hello() { //直接调用前端js方法 Clients.All.aa("abc"); } } }Hub
DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>title>
<script src="Scripts/jquery-1.6.4.js">script>
<script src="Scripts/jquery.signalR-2.2.3.js">script>
<script src="/signalr/js">script>
<script type="text/javascript">
$(function () {
//启动hub
$.connection.hub.start()
var conne = $.connection.myHub;
//申明客户端js方法
conne.client.aa = function (msg) {
$("#context").append("
" + msg)
}
$("#send").click(function () {
//直接调用后端方法
conne.server.hello();
})
})
script>
head>
<body>
<input type="text" id="txt" />
<input type="button" id="send" value="发送"/>
<div id="context">
div>
body>
html>
html
2,HubName/HubMethodName
using Microsoft.AspNet.SignalR.Hubs;
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; namespace WebApplication1 { [HubName("MyHub")] public class MyHub : Hub { [HubMethodName("Hello")] public void Hello() { //直接调用前端js方法 Clients.All.aa("abc"); } } }MyHub
3,ConnectionId
this.Context.ConnectionId;
四、Hub中的clients 和 groups属性
1,Clients
①T All { get; }
相当于持久连接中的 Broadcast。
②T AllExcept(params string[] excludeConnectionIds);
给排除本人所有人发送消息。(excludeConnectionIds排除的连接id)
③T Client(string connectionId);
跟Send操作就是一样的了。
④T Clients(IList
和Send操作的重载方法一样,可以给一批指定的人发送。
⑤T Group(string groupName, params string[] excludeConnectionIds);
给房间中的指定人发送消息: Clients.Group("room1", "asdfasdfads");
⑥T Groups(IList
给房间列表中的指定人发送消息; 【天然的聊天室功能】
⑦T User(string userId);
这个和Client是有区别的。 这个userId => this.Context.Request.User.Identity.Name 【form验证】
cookie中间件来做到singlar的身份验证。
userId 是你自己定义的一个标识。
T Users(IList
2,Groups
①Task Add(string connectionId, string groupName);
向组内添加链接
②Task Remove(string connectionId, string groupName);
删除组内的连接
五、GlobalHost
1,获取Hub的上下文
var hub = GlobalHost.ConnectionManager.GetHubContext();
2,对singlar的全局设置
GlobalHost.Configuration.MaxIncomingWebSocketMessageSize:
websocket模式下,消息的传输大小,如果大于默认的64k,那么就会出问题。
GlobalHost.Configuration.DisconnectTimeout:
websocket强制关闭的时间。 30 seconds
GlobalHost.Configuration.TransportConnectTimeout:
传输的超时时间。 5s
六、生成代理js
下载安装nuget: Microsoft.AspNet.SignalR.Utils
1,模板:signalr.exe ghp /path:《..\bin》 /o:《..\hub.js》
2,案例:
C:\Users\Hunter\Desktop\ConsoleApp3\packages\Microsoft.AspNet.SignalR.Utils.2.2.3\tools>signalr.exe ghp /path:C:\Users\Hunter\Desktop\ConsoleApp3\WebApplication2\bin /o:C:\Users\Hunter\Desktop\ConsoleApp3\WebApplication2\Scripts\hub.js
3,编译命令:
$(SolutionDir)packages\Microsoft.AspNet.SignalR.Utils.2.2.3\tools\signalr.exe ghp /path:$(SolutionDir)$(ProjectName)\$(OutDir) /o:$(SolutionDir)$(ProjectName)\Scripts\hub.js
4,替换代理js
七、支持跨域
①下载安装nuget: Microsoft.Owin.Cors
②配置项
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; using Microsoft.AspNet.SignalR; using Microsoft.Owin.Cors; [assembly: OwinStartup(typeof(WebApplication2.Startup))] namespace WebApplication2 { public class Startup { public void Configuration(IAppBuilder app) { // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888 app.UseCors(CorsOptions.AllowAll); app.MapSignalR(); } } }Startup
③生成代理js
④修改代理js
⑤html
DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>title>
<script src="Scripts/jquery-1.6.4.js">script>
<script src="Scripts/jquery.signalR-2.2.3.js">script>
<script src="Scripts/hub.js">script>
<script type="text/javascript">
$(function () {
//启动hub
$.connection.hub.start()
var conne = $.connection.myHub;
//申明客户端js方法
conne.client.aa = function (msg) {
$("#context").append("
" + msg)
}
$("#send").click(function () {
//直接调用后端方法
conne.server.hello();
})
})
script>
head>
<body>
<input type="text" id="txt" />
<input type="button" id="send" value="发送"/>
<div id="context">
div>
body>
html>
html
案例下载:https://pan.baidu.com/s/1GY_Io63qZeECbGbEH589fg
八、集群部署
使用redis:
nuget: Microsoft.AspNet.SignalR.Redis
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; using Microsoft.AspNet.SignalR; using Microsoft.Owin.Cors; [assembly: OwinStartup(typeof(WebApplication2.Startup))] namespace WebApplication2 { public class Startup { public void Configuration(IAppBuilder app) { // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888 //使用redis做底板 GlobalHost.DependencyResolver.UseRedis("localhost", 6379,string.Empty, "mykey"); app.UseCors(CorsOptions.AllowAll); app.MapSignalR(); } } }Startup
九、将singlar.exe 装入到 性能监视器
signlar.exe ipc 命令来安装性能监视器 [install performance counters]
signlar.exe upc 来卸载性能监视器 [uninstall performance counters]
十、HubPipeLine管道
实现:IHubPipelineModule
①入流: BuildIncoming 监控
②出流: BuildOutgoing 监控