一步一步學習SignalR進行實時通信_2_Persistent Connections
標簽(空格分隔): SignalR
前言
上一篇文章簡單的介紹了下SignalR,從此篇文章就開始對SignalR進行剖析。在介紹Persistent connections之前,先簡單介紹下安裝signalR的方法。
我的開發環境:win10+vs2013
安裝
- 首先我們新建一個空的MVC5的項目

- 通過Nuget[1]安裝SignalR,通過
Tools->Nuget Package Manager->Package Manager Console打開Package Manager Console - 輸入安裝語句
Install-Package Microsoft.AspNet.SignalR

可以看到添加了JQuery和SignalR2.0
Persistent Connections
Persistent Connections的字面意思是持久連接,它有點類似於Sockets,在服務端和客戶端都可以發送或接收數據。
映射並配置持久連接
如果我們要是實現基於
PersistentConnection的實時信息傳輸,首先第一步我們需要在服務器啟動時對_SignalR_進行配置。由於我們是基於_Owin_來實現_SignalR_的所以,我們在Startup中找到Configuration中配置,類似如果我們要實現其他的Owin框架我們也可以在這里進行配置。
-
映射
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; using SignalR_2.Models; //設置Owin的啟動項 [assembly: OwinStartup(typeof(SignalR_1.Startup))] namespace SignalR_· { public class Startup { public void Configuration(IAppBuilder app) { // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888 app.MapSignalR<EchoConnection>("/echo"); } } }通過
MapSignalR()方法來做映射,/echo表示將會映射到/echo,后面我我們轉到MapSignalR定義

MapSignalR()是一個擴展方法,它有許多重載方法,而我們主要關心的就是如圖所示的泛型方法。這個方法的TConnection要求是一個PersistentConnection類型。好了,到此為止我們已經知道我們需要什么了,沒必要繼續深究下去。通過以上的研究,很明顯,我們需要構造這么一個類去繼承
PersistentConnection來實現_SignalR_服務 -
實現SignalR服務
我們新建一個類叫做EchoConnection,代碼如下:using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Web; using Microsoft.AspNet.SignalR; namespace SignalR_1.Models { public class EchoConnection : PersistentConnection { /// <summary> /// 當前連接數 /// </summary> private static int _connections = 0; /// <summary> /// 連接建立時執行 /// </summary> /// <param name="request"></param> /// <param name="connectionId"></param> /// <returns></returns> protected override async Task OnConnected(IRequest request, string connectionId) { //原子操作,防止多條現成同時+1而只做一次變化 Interlocked.Increment(ref _connections); await Connection.Send(connectionId, "Hi, " + connectionId + "!"); await Connection.Broadcast("新連接 " + connectionId + "開啟. 當前連接數: " + _connections); } /// <summary> /// 連接關閉時執行 /// </summary> /// <param name="request"></param> /// <param name="connectionId"></param> /// <returns></returns> protected override Task OnDisconnected(IRequest request, string connectionId) { //原子操作,防止多條現成同時-1而只做一次變化 Interlocked.Decrement(ref _connections); return Connection.Broadcast(connectionId + " 連接關閉. 當前連接數: " + _connections); } /// <summary> /// 連接開始時執行 /// </summary> /// <param name="request"></param> /// <param name="connectionId"></param> /// <param name="data"></param> /// <returns></returns> protected override Task OnReceived(IRequest request, string connectionId, string data) { var message = connectionId + ">> " + data; return Connection.Broadcast(message); } } }我們定義了一個
EchoConnection類繼承PersistentConnetion,並寫了OnConnected、OnDisconnected、OnReceived、三個方法,大致功能是當客戶端連接時,服務器會通過Send()方法向它打招呼,參數是他的ConnectionId,並發送廣播消息給所有客戶端,並使總連接數+1,當客戶端關閉連接時,服務器會廣播給所有客戶端XXX連接關閉,並使總連接數-1 -
客戶端實現
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>persistent connections</title>
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
</head>
<body>
<h1>Echo service</h1>
<div>
<input type="text" id="text" />
<button id="send">Send</button>
</div>
<script>
$(function () {
var connection = $.connection("/echo");
connection.logging = true;
connection.received(function (data) {
$("body").append(data + "<br />");
});
connection.error(function (err) {
alert("存在一個錯誤. \n" +
"Error: " + err.message);
});
connection.start().done(function () {
$("#send").click(function () {
connection.send($("#text").val());
$("#text").val("").focus();
});
});
});
</script>
</body>
</html>
對上面的代碼有疑問看下面的圖片

如圖所示:左邊是客戶端的javascript代碼,右邊是服務器的代碼
當客戶端調用start方法時,會執行服務器的OnConnected方法
當客戶端點擊發送按鈕發送消息時,服務端會在OnReceived中接收到消息
當服務端對消息進行發送或廣播給客戶端時,客戶端receive會接收到此消息

結束語
這里通過PersistentConnection實現了在線聊天的簡單例子。
注意在項目運行期間,我出現過幾次程序集版本不對的情況,若出現此種情況,通過
Install-Package XXX重裝該程序集或Update-Package XXX升級該程序集,一般均可解決
參考文獻
SignalR Programming in Microsoft ASP.NET pdf 下載
NuGet 是免費、開源的包管理開發工具。 ↩︎
