SignalR 的 generated proxy 服務端 JavaScript 客戶端 generated proxy 非 generated proxy 什麼時候使用 generated proxy 如果你要給客戶端的方法註冊多個事件處理器,那麼你就不能使用 generated proxy。如果 ...
SignalR 的 generated proxy
服務端
public class ContosoChatHub : Hub { public void NewContosoChatMessage(string name, string message) { Clients.All.addContosoChatMessageToPage(name, message); } }
JavaScript 客戶端
generated proxy
var contosoChatHubProxy = $.connection.contosoChatHub; contosoChatHubProxy.client.addContosoChatMessageToPage = function (name, message) { console.log(name + ' ' + message); }; $.connection.hub.start().done(function () { // Wire up Send button to call NewContosoChatMessage on the server. $('#newContosoChatMessage').click(function () { contosoChatHubProxy.server.newContosoChatMessage($('#displayname').val(), $('#message').val()); $('#message').val('').focus(); }); });
非 generated proxy
var connection = $.hubConnection(); var contosoChatHubProxy = connection.createHubProxy('contosoChatHub'); contosoChatHubProxy.on('addContosoChatMessageToPage', function(name, message) { console.log(name + ' ' + message); }); connection.start().done(function() { // Wire up Send button to call NewContosoChatMessage on the server. $('#newContosoChatMessage').click(function () { contosoChatHubProxy.invoke('newContosoChatMessage', $('#displayname').val(), $('#message').val()); $('#message').val('').focus(); }); })
什麼時候使用 generated proxy
如果你要給客戶端的方法註冊多個事件處理器,那麼你就不能使用 generated proxy。如果你不使用 generated proxy ,那麼你就不能引用 "signalr/hubs" URL。
客戶端設置
首先需要引用jQuery,SignalR,signalr/hubs
<script src="Scripts/jquery-1.10.2.min.js"></script> <script src="Scripts/jquery.signalR-2.1.0.min.js"></script> <script src="signalr/hubs"></script>
如何引用動態的 generated proxy
ASP.NET MVC 4 or 5 Razor
<script src="~/signalr/hubs"></script>
ASP.NET MVC 3 Razor
<script src="@Url.Content("~/signalr/hubs")"></script>
ASP.NET Web Forms
<script src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script>
/signalr/hubs 是 SignalR 自動生成的,當你啟動調試的時候會在Script Documents 看到它
建立一個連接
建立一個連接 (generated proxy方式)
var contosoChatHubProxy = $.connection.contosoChatHub; contosoChatHubProxy.client.addContosoChatMessageToPage = function (name, message) { console.log(userName + ' ' + message); }; $.connection.hub.start() .done(function(){ console.log('Now connected, connection ID=' + $.connection.hub.id); }) .fail(function(){ console.log('Could not Connect!'); });
建立一個連接 (非 generated proxy方式)
var connection = $.hubConnection(); var contosoChatHubProxy = connection.createHubProxy('contosoChatHub'); contosoChatHubProxy.on('addContosoChatMessageToPage', function(userName, message) { console.log(userName + ' ' + message); }); connection.start() .done(function(){ console.log('Now connected, connection ID=' + connection.id); }) .fail(function(){ console.log('Could not connect'); });
$.connection.hub 和 $.hubConnection() 創建的對象是一樣的。
start 方法的非同步執行
start 方法是非同步執行的,它返回一個 jQuery Deferred 對象,你可以給 pipe, done, and fail 添加回調函數。
當你直接把 "Now connected" 代碼放在 start 方法後面,而不是放在 .done 的回調函數里,那麼 console.log 會在連接前就執行。
怎麼開啟跨域連接
首先需要安裝 Microsoft.Owin.Cors ,然後使用 Map 和 RunSignalR 代替 MapSignalR,跨域中間件只會在需要跨域的 SignalR 請求里執行。
using Microsoft.AspNet.SignalR; using Microsoft.Owin.Cors; using Owin; namespace MyWebApplication { public class Startup { public void Configuration(IAppBuilder app) { // Branch the pipeline here for requests that start with "/signalr" app.Map("/signalr", map => { // Setup the CORS middleware to run before SignalR. // By default this will allow all origins. You can // configure the set of origins and/or http verbs by // providing a cors options with a different policy. map.UseCors(CorsOptions.AllowAll); var hubConfiguration = new HubConfiguration { // You can enable JSONP by uncommenting line below. // JSONP requests are insecure but some older browsers (and some // versions of IE) require JSONP to work cross domain // EnableJSONP = true }; // Run the SignalR pipeline. We're not using MapSignalR // since this branch already runs under the "/signalr" // path. map.RunSignalR(hubConfiguration); }); } } }
如何處理連接的生命周期事件
SignalR 提供了下述你可以捕獲的生命周期事件。
- starting: 在任何數據發送之前執行。
- received: 當任何數據通過連接獲取到的時候執行。可以得到數據。
- connectionSlow: 當客戶端檢測到緩慢或者不流暢的連接的時候執行。
- reconnecting: 當潛在的協議重新開始連接的時候執行。
- reconnected: 當潛在的協議以及重新建立連接的時候執行。
- stateChanged: 當連接的狀態發生改變的時候執行。可以提供一個舊的和新的狀態(Connecting, Connected, Reconnecting, 或者 Disconnected)。
- disconnected: 當連接中斷以後執行。
捕獲 connectionSlow 事件 (generated proxy方式)
$.connection.hub.connectionSlow(function () { console.log('We are currently experiencing difficulties with the connection.') });
捕獲 connectionSlow 事件 (非generated proxy方式)
var connection = $.hubConnection(); connection.connectionSlow(function () { console.log('We are currently experiencing difficulties with the connection.') });
如何捕獲和處理異常
如果你不在服務端明確地打開詳細錯誤信息,那麼SignalR只會列出一些簡單的錯誤信息,你可以通過下麵的代碼開啟詳細錯誤信息記錄。
var hubConfiguration = new HubConfiguration(); hubConfiguration.EnableDetailedErrors = true; app.MapSignalR(hubConfiguration);
給錯誤事件添加一個捕獲方法
generated proxy 方式
$.connection.hub.error(function (error) { console.log('SignalR error: ' + error) });
非 generated proxy 方式
var connection = $.hubConnection(); connection.error(function (error) { console.log('SignalR error: ' + error) });
方法調用的時候捕獲異常
generated proxy 方式
contosoChatHubProxy.newContosoChatMessage(userName, message) .fail(function(error) { console.log( 'newContosoChatMessage error: ' + error) });
非 generated proxy 方式
contosoChatHubProxy.invoke('newContosoChatMessage', userName, message) .fail(function(error) { console.log( 'newContosoChatMessage error: ' + error) });
開啟客戶端日誌記錄
generated proxy 方式
$.connection.hub.logging = true; $.connection.hub.start();
非 generated proxy 方式
var connection = $.hubConnection(); connection.logging = true; connection.start();