# SignalR学习
ASP.NET SignalR 是为.NET 开发者提供即时通讯Web 应用的类库。即时通讯Web服务就是服务器将内容自动推送到已经连接的客户端,而不是服务器等待客户端发起一个新的数据请求。SignalR简化了构建实时应用的过程,它包括了一个Asp .Net服务器端库和一个Js端库,集成了数种常见的消息传输方式,如long polling,WebSocket,并提供相应的Api供开发人员选择如何调用,帮助其可以简单快速地实现客户端与服务器端相互间的实时通信。
当环境条件合适时,SignalR将WebSocket作为底层传输方式的优先实现,当然,它也能很高效地回退到其他技术。同时,SignalR提供了非常良好的Api以供远程调用(RPC) 浏览器中的js代码。
### SignalR的优点
1. SignalR 不仅能够自动管理连接,而且能够同时向所有的客户端广播消息,就像聊天室一样。你也能够发送消息到指定的客户端。SignalR提供的连接是持久的,它不像传统的HTTP连接需要为每次收发消息建立单独的连接。
2. SignalR 同时在服务端提供了远程过程调用协议(RPC),让你能够“主动”推送消息到浏览器中的客户端,而不像普通的Web服务一样的应答方式。
3. SignalR 应用能够运用到成千的客户端上,通过使用服务总线、SQL Server或者Redis。
4. SignalR 是开源的,能够通过GitHub很容易得到。
### 应用场景
1. 即时响应应用,例如:在线聊天,游戏,天气或者股票信息
2. 用户需要随时更新数据的网页运用,例如:仪表盘和监控运用,其他协同应用程序(文档协同操作)、工作流更新或者是即时表格
3. 高频繁从服务器更新的应用,例如:实时在线游戏
### 官方网址
1. https://docs.microsoft.com/en-us/aspnet/signalr/
2. https://github.com/SignalR/SignalR
### 运行效果图
### 核心代码
后台代码
using Microsoft.AspNet.SignalR; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Web; namespace MvcSignalR.Services { /// <summary> /// 数据交流类 /// </summary> public class ChatServiceHub : Hub { //所有的ConnectionId public static ConcurrentDictionary<string,DateTime> AllConnectionIDs = new ConcurrentDictionary<string, DateTime>(); //用户的ConnectionID,一个ID对应一个用户 public static ConcurrentDictionary<string, string> UserConnectionIDs = new ConcurrentDictionary<string, string>(); private Random rd = new Random(); public void Send(string message) { int i = 0; while (i < 10000) { i++; Thread.Sleep(100); Clients.Client(Context.ConnectionId).broadcastMessage(Context.ConnectionId, message + rd.Next(1000)); } } public void SendMessage(string message) { Clients.Client(Context.ConnectionId).receiveMessage(message + rd.Next(1000)); } public override Task OnConnected() { AllConnectionIDs.AddOrUpdate(Context.ConnectionId, DateTime.Now, (key, oldValue) => DateTime.Now); return base.OnReconnected(); } } }
前台代码
@{ ViewBag.Title = "QQ"; } <link href="~/Content/qq.css" rel="stylesheet" /> <h2></h2> <div class="qqBox"> <div class="BoxHead"> <div class="headImg"> <img src="~/Images/qq/1004.jpg" /> </div> <div class="internetName">signalR模拟QQ</div> </div> <div class="context"> <div class="conLeft"> <ul> <li> <div class="liLeft"><img src="~/Images/qq/1002.jpg" /></div> <div class="liRight"> <span class="intername">SignalR群</span> <span class="infor">厉害了</span> </div> </li> <li class="bg"> <div class="liLeft"><img src="~/Images/qq/1001.jpg" /></div> <div class="liRight"> <span class="intername">小华</span> <span class="infor">[流泪]</span> </div> </li> <li> <div class="liLeft"><img src="~/Images/qq/1002.jpg" /></div> <div class="liRight"> <span class="intername">SignalR交流群</span> <span class="infor">666</span> </div> </li> </ul> </div> <div class="conRight"> <div class="Righthead"> <div class="headName">小华</div> <div class="headConfig"> <ul> <li><img src="~/Images/qq/20170926103645_06.jpg" /></li> <li><img src="~/Images/qq/20170926103645_08.jpg" /></li> <li><img src="~/Images/qq/20170926103645_10.jpg" /></li> <li><img src="~/Images/qq/20170926103645_12.jpg" /></li> </ul> </div> </div> <div class="RightCont"> <ul class="newsList"></ul> </div> <div class="RightFoot"> <div class="footTop"> <ul> <li><img src="~/Images/qq/20170926103645_31.jpg" /></li> <li class="ExP"><img src="~/Images/qq/20170926103645_33.jpg" /></li> <li><img src="~/Images/qq/20170926103645_35.jpg" /></li> <li><img src="~/Images/qq/20170926103645_37.jpg" /></li> <li><img src="~/Images/qq/20170926103645_39.jpg" /></li> <li><img src="~/Images/qq/20170926103645_41.jpg" alt="" /></li> <li><img src="~/Images/qq/20170926103645_43.jpg" /></li> <li><img src="~/Images/qq/20170926103645_45.jpg" /></li> </ul> </div> <div class="inputBox"> <textarea id="dope" style=" 99%;height: 75px; border: none;outline: none;" name=""></textarea> <button class="sendBtn">发送(s)</button> </div> </div> </div> </div> </div> @section scripts{ <script src="~/Scripts/jquery.signalR-2.3.0.js"></script> <script src="~/signalr/hubs"></script> <script src="~/Scripts/qq.js"></script> }
js代码
$(function () { // Declare a proxy to reference the hub. var chat = $.connection.chatServiceHub; // 接受信息 chat.client.receiveMessage = function (message) { receiveMessage(message); }; $.connection.hub.start(); // 左边列表 $('.conLeft li').on('click', function () { $(this).addClass('bg').siblings().removeClass('bg'); var intername = $(this).children('.liRight').children('.intername').text(); $('.headName').text(intername); $('.newsList').html(''); }); //发送信息 $('.sendBtn').on('click', function () { var news = $('#dope').val(); if (news == '') { alert('不能为空'); } else { chat.server.sendMessage(news); sendMessage(news); $('#dope').val(''); } }); function sendMessage(message) { var str = ''; str += '<li>' + '<div class="nesHead"><img src="/Images/qq/1004.jpg"/></div>' + '<div class="news"><img class="jiao" src="/Images/qq/20170926103645_03_02.jpg">' + message + '</div>' + '</li>'; $('.newsList').append(str); $('.conLeft').find('li.bg').children('.liRight').children('.infor').text(message); $('.RightCont').scrollTop($('.RightCont')[0].scrollHeight); } function receiveMessage(message) { var answer = ''; answer += '<li>' + '<div class="answerHead"><img src="/Images/qq/1003.jpg"/></div>' + '<div class="answers"><img class="jiao" src="/Images/qq/jiao.jpg">' + message + '</div>' + '</li>'; $('.newsList').append(answer); $('.RightCont').scrollTop($('.RightCont')[0].scrollHeight); } });
### git地址(Demo)
https://github.com/jasonhua95/MvcSignalR.git