本章和人人分享的内容是运用Signal R框架竖立个浅易的群聊功用,主要解说如安在.Net的MVC中运用这个框架,由于这个项目有官方文档(固然全英文),背面也不盘算写分享篇了,主要目标是让朋侪们在须要运用Web及时通讯的时刻有更多一种解决方案,毕竟这是微软主推的一种解决方案之一。
SignalR网上简介
ASP.NET SignalR 是为 ASP.NET 开发人员供应的一个库,可以简化开发人员将及时 Web 功用增添到运用顺序的历程。及时 Web 功用是指如许一种功用:当所衔接的客户端变得可用时服务器代码可以马上向其推送内容,而不是让服务器守候客户端请求新的数据。
SignalR固然也供应了异常简朴易用的高阶API,使服务器端可以单个或批量挪用客户端上的JavaScript函数,而且异常 方便地举行衔接治理,比方客户端衔接到服务器端,或断开衔接,客户端分组,以及客户端受权,运用SignalR都异常 轻易完成。
SignalR将与客户端举行及时通讯带给了ASP .NET 。固然如许既好用,而且也有充足的扩大性。之前用户须要革新页面或运用Ajax轮询才完成的及时显现数据,如今只需运用SignalR,就可以够简朴完成了。最主要的是您无需从新竖立项目,运用现有ASP .NET项目即可无缝运用SignalR。
群聊实例结果
咋们先来看看测试用例的结果吧,这里是线上结果链接:神牛谈天室(:1001/home/shenniuchat),结果图:
界面及其简朴,款式这里就不斟酌了,主假如展现其用法,这里涉及到的功用有:
1. 统计在线人数目
2. 显如今线人数的昵称和衔接体式格局(本测试用例支撑webSockets和longPolling(长衔接))
3. 群聊信息
MVC中怎样运用SignalR
起首,我们寻常做法竖立MVC的Web项目,然后经由过程Nuget控制台敕令: Install-package Microsoft.AspNet.SignalR 到场SignalR的依靠,自动增添的包以下:
<package id="Microsoft.AspNet.SignalR" version="2.2.2" targetFramework="net45" /> <package id="Microsoft.AspNet.SignalR.Core" version="2.2.2" targetFramework="net45" /> <package id="Microsoft.AspNet.SignalR.JS" version="2.2.2" targetFramework="net45" /> <package id="Microsoft.AspNet.SignalR.SystemWeb" version="2.2.2" targetFramework="net45" />
而且自动往MVC项目中的Script文件夹中增添相干的js文件:
jquery.signalR-2.2.2.min.js jquery.signalR-2.2.2.js
然后,我们须要在项目一级目次竖立一个文件称号为Startup.cs的类,内里主要内容补全不下:
1 [assembly: OwinStartup(typeof(Stage.Api.Extend.Startup))] 2 namespace Stage.Api.Extend 3 { 4 public class Startup 5 { 6 public void Configuration(IAppBuilder app) 7 { 8 app.MapSignalR("/chat", new Microsoft.AspNet.SignalR.HubConfiguration 9 {10 EnableDetailedErrors = true,11 EnableJavaScriptProxies = true12 });13 }14 }15 }
起首我们从上往下剖析注重点:
1. OwinStartup(Type) 组织函数通报的是一个类型,而这个类型对应的就是我们竖立的Startup类,这个经由过程这个组织函数类标记肇端位置;
2. namespace Stage.Api.Extend 是我项目标定名空间,这个可以随意定义;
3. public void Configuration(IAppBuilder app) 函数是牢固必需的,这里顺序会起首进入这个要领实行内里的逻辑代码;
4. app.MapSignalR 是扩大的IAppBuilder接口要领,他有多种表现形式,这里我挑选的是 public static IAppBuilder MapSignalR(this IAppBuilder builder, string path, HubConfiguration configuration); ,这里看有点类似于咋们MVC的路由,这里主要注重的是这个Path参数,在前端页面的时刻须要用到这个途径;
到这里背景须要的设置实在已就完成了,下面是细致须要操纵的营业逻辑处置惩罚类,新建一个类(这里我取名为ChatHub)并继续Hub(这是SignalR框架供应),然后内里的逻辑代码以下:
1 public class ChatHub : Hub 2 { 3 // 4 public int Num = 10001; 5 public static List<MoHubUser> _Users = new List<MoHubUser>(); 6 7 /// <summary> 8 /// 增添谈天人 9 /// </summary>10 /// <param name="user"></param>11 public void AddUser(MoHubUser user)12 {13 14 user.Id = Context.ConnectionId;15 if (!_Users.Any(b => b.Id == user.Id))16 {17 _Users.Add(user);18 }19 20 //Clients.All.newUser(user);21 Clients.All.userList(_Users);22 }23 24 /// <summary>25 /// 发送信息26 /// </summary>27 /// <param name="user"></param>28 /// <param name="message"></param>29 public void SendAll(MoHubUser user, string message)30 {31 Clients.All.addNewMessageToPage(user, message);32 }33 34 /// <summary>35 /// 某个谈天人退出是,关照一切在线人从新加载谈天人数36 /// </summary>37 /// <param name="stopCalled"></param>38 /// <returns></returns>39 public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)40 {41 var user = _Users.SingleOrDefault(x => x.Id == Context.ConnectionId);42 if (user != null)43 {44 _Users.Remove(user);45 Clients.All.userList(_Users);46 }47 return base.OnDisconnected(stopCalled);48 }49 }
上面的3个要领离别做了:增添谈天人到List,发送信息到客户端,某个衔接失效后关照各个有用的谈天人从新加载信息;这里值得关注的是经由过程从新 public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) 要领来完成捕捉并移除失效衔接(这里是谈天人的信息);整篇测试用例经由过程Context.ConnectionId来保证衔接的唯一性,只需有新的链接请求,那末服务端就会分派一个唯一串给这个链接,当客户端封闭页面或封闭链接这个是有就可以在OnDisconnected要领中捕捉到这个失效的链接的ConnectionId,如许就达到了移除失效谈天人的请求了;为了代码的方便性,这里竖立了一个谈天人信息类:
1 public class MoHubUser2 {3 4 public string Id { get; set; }5 public string NickName { get; set; }6 public string TransportMethod { get; set; }7 }
到这里背景的谈天室代码就完成了就是这么简朴;我们再来看试图中怎样来写代码,这里我先给出我的html规划代码:
1 @{ 2 ViewBag.Title = "神牛谈天室 - SignalR"; 3 } 4 <style type="text/css"> 5 .div_left { 6 width: 70%; 7 float: left; 8 } 9 10 .div_right {11 width: 28%;12 float: left;13 }14 15 .ul {16 list-style: none;17 border: 1px solid #ccc;18 height: 500px;19 overflow-y: scroll;20 color: black;21 }22 23 .ul li {24 padding-top: 5px;25 padding-right: 25px;26 }27 28 .ul_user {29 list-style: none;30 }31 32 .ul_user li {33 padding-top: 5px;34 }35 36 .send {37 position: relative;38 background: #eae7e7;39 border-radius: 5px; /* 圆角 */40 padding-top: 4px;41 padding-left: 5px;42 margin-top: 13px;43 }44 45 .send .arrow {46 position: absolute;47 top: -16px;48 font-size: 0;49 border: solid 8px;50 border-color: #fff #fff #eae7e7 #fff;51 }52 </style>53 <h3>@ViewBag.Title 在线人数:<span id="sapnUserTotal">0</span>人</h3>54 <div class="container text-left">55 <div class="div_left">56 <ul class="ul" id="discussion"></ul>57 <textarea rows="5" class="form-control" id="message" maxlength="500" placeholder="最先谈天. . ." style="max-width: 100%"></textarea><br />58 <input type="button" id="sendmessage" value="发 送" class="btn btn-default" />59 <input type="hidden" id="displayname" />60 </div>61 <div class="div_right">62 <ul id="users" class="ul_user"></ul>63 </div>64 </div>65 66 <script src="~/Scripts/jquery.signalR-2.2.2.min.js"></script>67 @*<script src="~/chat/hubs"></script>*@
客户端这里写法大抵有两种挑选,一种直接运用生成的代办来操纵,一种不必自动生成的代办采纳手动竖立代办的体式格局;为了内容的简洁性,这里只简朴解说下自动生成的代办体式格局,而更多的是分享手动竖立代办链接的体式格局;
运用生成的代办猎取链接
起首,我们须要经由过程Script标签来援用一下自动生成代办的途径: <script src="~/chat/hubs"></script> ,注重啦这里的途径/chat对应的就是咋们在前面Startup.cs文件中设置 app.MapSignalR("/chat" 途径,而背面/hubs牢固的写法(最少现在我还没更多的实验过),只要先运用了这个~/chat/hubs,才在背面运用生成的代办,先上段代码:
1 var chat = $.connection.chatHub; 2 chat.client.newUser = function (user) { 3 $("#users").append(' <li><strong>' + user.NickName + '[' + user.TransportMethod + ']</strong></li>'); 4 }; 5 6 chat.client.userList = function (users) { 7 console.log(users); 8 $("#sapnUserTotal").html(users.length); 9 $.each(users, function (i, item) {10 $("#users").append(' <li>[' + item.TransportMethod + '] <strong>' + item.NickName + '</strong>(' + item.Id + ')</li>');11 });12 };13 chat.client.addNewMessageToPage = function (user, message) {14 console.log(user);15 $("#discussion").append(' <li ><span><strong>' + user.NickName + '[' + user.TransportMethod + ']</strong>:</span><div class="send">' + message + '<div class="arrow"></div></div></li>');16 };17 //connection.hub.start({ transport: ['webSockets', 'longPolling'] }).done(function () {18 // my.TransportMethod = connection.hub.transport.name;19 // chat.server.addUser(my);20 21 // $('#sendmessage').click(function () {22 // //console.log(chat);23 // var content = $.trim($('#message').val());24 // if (content.length <= 0) { $('#message').val('').focus(); return; }25 // chat.server.sendAll(my, content);26 // $('#message').val('').focus();27 // });28 //}).fail(function () {29 // alert("链接谈天室失利,请从新革新页面。");30 //});
咋们逐步来剖析下代码注重点:
1. var chat = $.connection.chatHub; 这里的chatHub对应的就是咋们竖立的并继续Hub的ChatHub类,由于js变量开首都是小写,所以这里是chatHub,这句活就示意链接到咋们后端了ChatHub类了,然后就可以够运用内里的要领啦(这类有点类似于初期的webform中某种ajax请求的写法)
2. 经由过程chat.client.xxx来接收服务端关照的音讯,而这个xxx对应的要领称号和咋们后端的Clients.All.xxx,本章实例对应的是:chat.client.userList = function (users){}对应Clients.All.userList(_Users);如许后端就可以直接关照客户端的对应要领了;注重这里我后端Clients.All用的是关照悉数客户端的意义,假如您须要关照指定的链接须要用到的是: T Client(string connectionId); 要领
3. chat.client是后端挪用客户端,那相对的chat.server就是客户端请求服务端,和上面一样经由过程chat.server.xxx来指定请求的服务端要领,注重这个时刻服务端要领指的是继续类Hub的子类的大众要领(本篇对应的是:chat.server.sendAll(my, content)对应ChatHub.cs文件中的 public void SendAll(MoHubUser user, string message) 函数)
4. connection.hub.start({ transport: ['webSockets', 'longPolling'] }) 来指定运转的交互协定
以上就是运用生成代办的体式格局,根据上面的注重点来写应当不是题目;
运用手动竖立反向代办来链接
不采纳生成的代码的体式格局,我们只须要修正前端就好了,背景代码不必变或设置不必更改;起首我们把上面说的Script援用自动代办的代码去掉,由于这个时刻不须要了,我们照样先上代码:
1 var my = { NickName: "神牛001", TransportMethod: "" }; 2 var connection = $.hubConnection("/chat/hubs"); 3 var chat = connection.createHubProxy('chatHub'); 4 5 chat.on("userList", function (users) { 6 console.log(users); 7 $("#sapnUserTotal").html(users.length); 8 $("#users").html(""); 9 $.each(users, function (i, item) {10 $("#users").append(' <li>[' + item.TransportMethod + '] <strong>' + item.NickName + '</strong>(' + item.Id + ')</li>');11 });12 });13 14 chat.on("addNewMessageToPage", function (user, message) {15 console.log(user);16 $("#discussion").append(' <li ><span><strong>' + user.NickName + '[' + user.TransportMethod + ']</strong>:</span><div class="send">' + message + '<div class="arrow"></div></div></li>');17 18 var div = document.getElementById('discussion');19 //div.scrollTop = div.scrollHeight;20 div.scrollTop = 999999;21 });22 23 var nickName = prompt("请输入一个昵称:", my.NickName);24 my.NickName = nickName.length > 0 ? nickName : my.NickName;25 $('#displayname').val(nickName);26 $('#message').focus();27 28 29 connection.start({ transport: ['webSockets', 'longPolling'] }).done(function () {30 31 my.TransportMethod = connection.transport.name;32 //console.log(my.TransportMethod);33 chat.invoke("addUser", my);34 35 $('#sendmessage').click(function () {36 var content = $.trim($('#message').val());37 if (content.length <= 0) { $('#message').val('').focus(); return; }38 39 chat.invoke("sendAll", my, content);40 $('#message').val('').focus();41 });42 });
一样列出以下注重点:
1. var connection = $.hubConnection("/chat/hubs"); 竖立链接,这里的path一样对应后端的 app.MapSignalR("/chat" ,途径保持一致
2. var chat = connection.createHubProxy('chatHub'); 来竖立反向代办链接,这里的name:chatHub对应的是后端的ChatHub类称号
3. 经由过程on("xxx",function(){})函数来绑定服务端关照客户端的事宜,xxx对应Clients.All.xxx中的xxx
4. connection.start({ transport: ['webSockets', 'longPolling'] }) 来设置许可的链接体式格局,并最先链接
5. connection.transport.name来猎取链接的体式格局称号,默许start不设置的话有这么几种:webSockets,foreverFrame,serverSentEvents,longPolling
6. chat.invoke("xxx", param1, param2)经由过程invoke来映照继续类Hub的类的大众要领,这里实例对应的是: chat.invoke("sendAll", my, content) 对应 public void SendAll(MoHubUser user, string message)
写在末了
到此假如满足以上注重点,那末基础SignalR就可以链接运用胜利了,注重点比较多不过都是总结的履历,愿望多朋侪们有协助;在写本文的时刻恰好有朋侪在看我git开源的LovePicture.Web项目,听说他们也将最先尝试在公司中运用Netcore来构建运用,我为此以为幸运也愉快,幸运可以把我项目当作类型,愉快是NetCore也越来越有影响力了哈哈;假如以为本篇还可以,或给您收成,无妨点个引荐,感谢!!!
以上就是SignalR简介及用法引见的细致内容,更多请关注ki4网别的相干文章!