ASP.NET SignalR是一個ASP.NET 下的類庫,可以在ASP.NET 的Web項目中實現實時通信。實際上 Asp.net SignalR 2 實現 服務端消息推送到Web端, 更加簡單
下面通過一個簡單例子介紹SignalR的用法:
項目結構如下:

為了支持 SignalR,使用 NuGet 控制台往項目中安裝了 SignalR,這里我用的是2.1.2版本
安裝命令:
Install-Package Microsoft.AspNet.SignalR -Version 2.1.2
更新命令:
UPDATE-Package Microsoft.AspNet.SignalR -Version 2.4.0 UPDATE-Package jQuery -Version 1.8.2
首先我們新建一個SignalR集線器代理類MyChatHub,該類需要繼承 Hub 類,並創建一個業務邏輯需要的方法,本例中主要應用到的方法:
//調用所有客戶端的SendMessage方法 Clients.All.SendMessage(message);
MyChatHub完整類如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; //先在Nuget上搜索Microsoft.AspNet.SignalR安裝 using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; namespace SignalRDEMO { /// <summary> /// 自定義SignalR集線器代理類名稱 /// </summary> [HubName("myChatHub")] public class MyChatHub : Hub { /// <summary> /// 推送至所有客戶端 /// </summary> /// <param name="message">消息</param> public void Send(string message) { //調用所有客戶端的SendMessage方法 Clients.All.SendMessage(message); } } }
接着新建一個web頁面WebForm1.aspx,在頁面中實例化 SignalR 類,做具體業務邏輯代碼如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="SignalRDEMO.WebForm1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>SignalR實時消息推送到客戶端</title> <script src="Scripts/jquery-1.8.2.js"></script> <!--引用SignalR庫--> <script src="Scripts/jquery.signalR-2.1.2.min.js"></script> <!--引用自動生成的SignalR集線器(Hub)腳本.在運行的時候在瀏覽器的Source下可看到--> <script src="/signalr/hubs" type="text/javascript"></script> <script type="text/javascript"> $(function () { //引用服務端的集線器代理類 var chat = $.connection.myChatHub; //定義服務器端調用的客戶端SendMessage方法來顯示新消息 chat.client.SendMessage = function (message) { ShowMessage(message); }; //$.extend(chat.client, { // SendMessage: function (message) { // ShowMessage(message); // } //}); //設置焦點到輸入框 $('#message').focus(); //開始連接服務器 $.connection.hub.start().done(function () { $('#SendMessage').click(function () { //調用服務器端定義的Send方法 chat.server.send($('#message').val()); //清空輸入框信息並獲取焦點 $('#message').val('').focus(); }); }); }); //向頁面添加消息 function ShowMessage(message) { $('#list').append('<li>' + message + '</li>'); } </script> </head> <body> <form id="form1" runat="server"> <div> <input type="text" id="message" /> <input type="button" id="SendMessage" value="發送" /> <ul id="list"> </ul> </div> </form> </body> </html>
OK了,可以運行網站試試,看是否報錯,很遺憾還是報錯了,錯誤信息如下:
The following errors occurred while attempting to load the app. - No assembly found containing an OwinStartupAttribute. - No assembly found containing a Startup or [AssemblyName].Startup class. To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of "false" in your web.config. To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config.
運行之后,應該不少朋友有這樣的報錯(可能是中文的錯誤提示)!
看着錯誤提示,其實直接就知道大概什么情況了,OwinStartupAttribute 沒有找到!
緊跟着提示了兩種做法,也就是這兩種做法誤導了初學者!
我們按照提示,於是在網上搜索得到的做法是在Web.config中添加:
<appSettings>
<add key="owin:AutomaticAppStartup" value="false" />
</appSettings>
之后再次運行網站看看是否報錯,我去還是報錯啊,說明上面做法不啟用,只能去調試看看,調試發現,瀏覽到業務所在頁面,報錯:
GET http://localhost:10292/signalr/hubs 404 (Not Found) Uncaught TypeError: Cannot read property 'client' of undefined
到網上搜了很多,最后搜到官方使用 SignalR 步驟:
http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr
其中第6和7步驟解決了問題就是需要新建一個類Startup
然后給出了代碼(注意紅色):
using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(SignalRChat.Startup))] namespace SignalRChat { public class Startup { public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here app.MapSignalR(); } } }
果然,當添加完這樣的類之后,問題解決了,業務功能實現了( 去掉之前web.config中加入的錯誤代碼)!
所以要切記使用SignalR需要同時增加一個Starup.cs, 用於Owin
運行效果圖如下:

每一個使用的OWin組件的Web框架都需要一個StartUp入口類,用來聲明OWin組件:
1. 項目會自動掃描程序集根下的名為StartUp的類作為入口類
2. 通過添加 [assembly: OwinStartup(typeof(SignalRDEMO.Startup))] 標簽標記入口類
3. 如果你的啟動類不在當前命名空間下 <add key="owin:AppStartup" value="[NameSpace].Startup" />
4. 由於第一點的存在,所以如果有名為StartUp的類,並且不是入口點,需要使用 <add key="owin:AutomaticAppStartup" value="false" />
