天天看點

一步一步學習SignalR進行實時通信_2_Persistent Connections

一步一步學習SignalR進行實時通信\_2_Persistent Connections

<code>SignalR</code>

<a href="#%E4%B8%80%E6%AD%A5%E4%B8%80%E6%AD%A5%E5%AD%A6%E4%B9%A0signalr%E8%BF%9B%E8%A1%8C%E5%AE%9E%E6%97%B6%E9%80%9A%E4%BF%A12persistent-connections">一步一步學習SignalR進行實時通信_2_Persistent Connections</a>

<a href="#%E5%89%8D%E8%A8%80">前言</a>

<a href="#%E5%AE%89%E8%A3%85">安裝</a>

<a href="#persistent-connections">Persistent Connections</a>

<a href="#%E6%98%A0%E5%B0%84%E5%B9%B6%E9%85%8D%E7%BD%AE%E6%8C%81%E4%B9%85%E8%BF%9E%E6%8E%A5">映射并配置持久連接配接</a>

<a href="#%E7%BB%93%E6%9D%9F%E8%AF%AD">結束語</a>

<a href="#%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE">參考文獻</a>

我的開發環境:win10+vs2013

首先我們建立一個空的MVC5的項目

輸入安裝語句<code>Install-Package Microsoft.AspNet.SignalR</code>

可以看到添加了JQuery和SignalR2.0
如果我們要是實作基于<code>PersistentConnection</code>的實時資訊傳輸,首先第一步我們需要在伺服器啟動時對SignalR進行配置。由于我們是基于Owin來實作SignalR的是以,我們在<code>Startup</code>中找到<code>Configuration</code>中配置,類似如果我們要實作其他的<code>Owin</code>架構我們也可以在這裡進行配置。

映射

<code>using System;</code>

<code>using System.Threading.Tasks;</code>

<code>using Microsoft.Owin;</code>

<code>using Owin;</code>

<code>using SignalR_2.Models;</code>

<code>//設定Owin的啟動項</code>

<code>[assembly: OwinStartup(typeof(SignalR_1.Startup))]</code>

<code>namespace SignalR_·</code>

<code>{</code>

<code>public class Startup</code>

<code>public void Configuration(IAppBuilder app)</code>

<code>// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888</code>

<code>app.MapSignalR&lt;EchoConnection&gt;("/echo");</code>

<code>}</code>

通過<code>MapSignalR()</code>方法來做映射,<code>/echo</code>表示将會映射到<code>/echo</code>,後面我我們轉到MapSignalR定義

<code>MapSignalR()</code>是一個擴充方法,它有許多重載方法,而我們主要關心的就是如圖所示的泛型方法。這個方法的<code>TConnection</code>要求是一個<code>PersistentConnection</code>類型。

好了,到此為止我們已經知道我們需要什麼了,沒必要繼續深究下去。通過以上的研究,很明顯,我們需要構造這麼一個類去繼承<code>PersistentConnection</code>來實作SignalR服務

實作SignalR服務

我們建立一個類叫做<code>EchoConnection</code>,代碼如下:

<code>using System.Collections.Generic;</code>

<code>using System.Linq;</code>

<code>using System.Threading;</code>

<code>using System.Web;</code>

<code>using Microsoft.AspNet.SignalR;</code>

<code></code>

<code>namespace SignalR_1.Models</code>

<code>public class EchoConnection : PersistentConnection</code>

<code>/// &lt;summary&gt;</code>

<code>/// 目前連接配接數</code>

<code>/// &lt;/summary&gt;</code>

<code>private static int _connections = 0;</code>

<code>/// 連接配接建立時執行</code>

<code>/// &lt;param name="request"&gt;&lt;/param&gt;</code>

<code>/// &lt;param name="connectionId"&gt;&lt;/param&gt;</code>

<code>/// &lt;returns&gt;&lt;/returns&gt;</code>

<code>protected override async Task OnConnected(IRequest request, string connectionId)</code>

<code>//原子操作,防止多條現成同時+1而隻做一次變化</code>

<code>Interlocked.Increment(ref _connections);</code>

<code>await Connection.Send(connectionId, "Hi, " + connectionId + "!");</code>

<code>await Connection.Broadcast("新連接配接 " + connectionId + "開啟. 目前連接配接數: " + _connections);</code>

<code>/// 連接配接關閉時執行</code>

<code>protected override Task OnDisconnected(IRequest request, string connectionId)</code>

<code>//原子操作,防止多條現成同時-1而隻做一次變化</code>

<code>Interlocked.Decrement(ref _connections);</code>

<code>return Connection.Broadcast(connectionId + " 連接配接關閉. 目前連接配接數: " + _connections);</code>

<code>/// 連接配接開始時執行</code>

<code>/// &lt;param name="data"&gt;&lt;/param&gt;</code>

<code>protected override Task OnReceived(IRequest request, string connectionId, string data)</code>

<code>var message = connectionId + "&gt;&gt; " + data;</code>

<code>return Connection.Broadcast(message);</code>

我們定義了一個<code>EchoConnection</code>類繼承<code>PersistentConnetion</code>,并寫了<code>OnConnected</code>、<code>OnDisconnected</code>、<code>OnReceived</code>、三個方法,大緻功能是當用戶端連接配接時,伺服器會通過Send()方法向它打招呼,參數是他的ConnectionId,并發送廣播消息給所有用戶端,并使總連接配接數+1,當用戶端關閉連接配接時,伺服器會廣播給所有用戶端XXX連接配接關閉,并使總連接配接數-1

用戶端實作

<code>&lt;!DOCTYPE html&gt;</code>

<code>&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;</code>

<code>&lt;head&gt;</code>

<code>&lt;title&gt;persistent connections&lt;/title&gt;</code>

<code>&lt;script src="Scripts/jquery-1.10.2.min.js"&gt;&lt;/script&gt;</code>

<code>&lt;script src="Scripts/jquery.signalR-2.0.0.min.js"&gt;&lt;/script&gt;</code>

<code>&lt;/head&gt;</code>

<code>&lt;body&gt;</code>

<code>&lt;h1&gt;Echo service&lt;/h1&gt;</code>

<code>&lt;div&gt;</code>

<code>&lt;input type="text" id="text" /&gt;</code>

<code>&lt;button id="send"&gt;Send&lt;/button&gt;</code>

<code>&lt;/div&gt;</code>

<code>&lt;script&gt;</code>

<code>$(function () {</code>

<code>var connection = $.connection("/echo");</code>

<code>connection.logging = true;</code>

<code>connection.received(function (data) {</code>

<code>$("body").append(data + "&lt;br /&gt;");</code>

<code>});</code>

<code>connection.error(function (err) {</code>

<code>alert("存在一個錯誤. \n" +</code>

<code>"Error: " + err.message);</code>

<code>connection.start().done(function () {</code>

<code>$("#send").click(function () {</code>

<code>connection.send($("#text").val());</code>

<code>$("#text").val("").focus();</code>

<code>&lt;/script&gt;</code>

<code>&lt;/body&gt;</code>

<code>&lt;/html&gt;</code>

對上面的代碼有疑問看下面的圖檔

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

這裡通過PersistentConnection實作了線上聊天的簡單例子。

注意在項目運作期間,我出現過幾次程式集版本不對的情況,若出現此種情況,通過<code>Install-Package XXX</code> 重裝該程式集或<code>Update-Package XXX</code>更新該程式集,一般均可解決

<a href="http://files.cnblogs.com/files/Jack-Blog/SignalR.rar" target="_blank">源碼下載下傳</a>

<a href="http://pan.baidu.com/s/1qcfx0" target="_blank">SignalR Programming in Microsoft ASP.NET pdf 下載下傳</a>

繼續閱讀