您好,登錄后才能下訂單哦!
本篇內容主要講解“Asp.net如何通過SignalR2進行實時聊天”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Asp.net如何通過SignalR2進行實時聊天”吧!
Asp.net SignalR是微軟為實現實時通信的一個類庫。
一般情況下,signalR會使用JavaScript的長輪詢(long polling)的方式來實現客戶端和服務器通信,隨著Html5中WebSockets出現,SignalR也支持WebSockets通信。
另外SignalR開發的程序不僅僅限制于宿主在IIS中,也可以宿主在任何應用程序,包括控制臺,客戶端程序和Windows服務等,另外還支持Mono,這意味著它可以實現跨平臺部署在Linux環境下。
SignalR將整個信息的交換封裝起來,客戶端和服務器都是使用JSON來溝通的,在服務端聲明的所有Hub信息,都會生成JavaScript輸出到客戶端,.NET則依賴Proxy來生成代理對象,而Proxy的內部則是將JSON轉換成對象。
客戶端和服務端的具體交互情況如下圖所示:
這種傳輸方式當然是需要對HTML5兼容支持。如果客戶端不支持HTML5 標準,那么你可以使用其他方式。
WebSocket: (前提是服務器和客戶端都可以支持WebSocket )。WebSocket 是唯一的能夠支持服務器和客戶端建立真正持久的雙向連接的傳輸方式,但是就是WebSocket要求的條件比較苛刻。
WebSocket真正能夠支持只是在最新的IE 瀏覽器、Chrome、Firefox和一些其他的瀏覽器比如Opera 和 Safari。
Server Sent Events (SSE)服務端發送事件 :就是我們常說的EventSource (除了IE的其他瀏覽器都支持支持服務器發送事件)。
下面的傳輸方式都是建立在Comet Web應用模型上。這種傳輸方式會在瀏覽器或者其他客戶端保持一個長連接的HTTP請求,服務器可以利用這個請求將數據推送到客戶端,而不用等客戶端單獨去請求數據。
Forever Frame:(只有IE瀏覽器支持)Forever Frame 會創建一個隱藏的IFrame ,這個IFrame 會向服務器發起一個端點請求,但是這個請求不會結束。服務器會不停的發送腳本到客戶端馬上執行,提供一個從服務器端到客戶端的單向實時連接。服務端到客戶端和客戶端到服務端分別是兩個不同的連接,就像一個標準的HTTP請求,一旦有數據需要發送就會創建一個新的連接。
Ajax Long Polling長輪詢:長輪詢不會創建一個持久的連接,它是會保持一個客戶端與服務器的連接,直到服務器做出應答就會立即關閉,然后創建一個新的連接。當連接重置的時候這會導致一些延遲。
Http Persisten Connection(持久連接)對象:用來解決長時間連接的功能。
還可以由客戶端主動向服務器要求數據,而服務器端不需要實現太多細節,只需要處理PersistentConnection 內所提供的五個事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。
Hub(集線器)對象:用來解決實時(realtime)信息交換的功能,服務端可以利用URL來注冊一個或多個Hub,只要連接到這個Hub,就能與所有的客戶端共享發送到服務器上的信息,同時服務端可以調用客戶端的腳本。
SignalR將整個信息的交換封裝起來,客戶端和服務器都是使用JSON來溝通的,在服務端聲明的所有Hub信息,都會生成JavaScript輸出到客戶端,.NET則依賴Proxy來生成代理對象,而Proxy的內部則是將JSON轉換成對象。
下面的圖展示了Hub和持久連接的關系,讓你對底層的傳輸技術一目了然。
原文參考:教程:通過 SignalR 2 進行實時聊天
使用vs2012創建一個新的ASP.NET Web Application項目。
在解決方案中添加SignalR Hub類選項,然后創建文件ChatHub.cs。此步驟將創建ChatHub.cs類文件并添加一組腳本文件和 SignalR 支持到項目的程序集引用。
注意:可以使用NuGet命令 install-package Microsoft.AspNet.SignalR
來引用SignalR到項目中
然后在ChatHub類中輸入下面這段代碼。
using Microsoft.AspNet.SignalR; namespace WebApplication2 { public class ChatHub : Hub { //定義可以被網頁腳本訪問的公共方法 public void Send(string name, string message) //在客戶端可以使用hub.server.send()方法調用。 { // 客戶端通過調用broadcastMessage來獲取服務端數據 Clients.All.broadcastMessage(name, message);//在客戶端通過hub.client.broadcastMessage=function(){…}定義這個回調函數。 } } }
在ChatHub類中,可以看到它繼承自Microsoft.AspNet.SignalR.Hub類。從Hub類派生出類是構建SignalR應用程序的有用方式。在這個類(ChatHub)中定義的公共方法可以被網頁內的腳本訪問。
在這段代碼中(ChatHub類),客戶端通過調用ChatHub.Send方法,并把名稱和消息內容做為參數傳遞給ChatHub。而ChatHub則通過Clients.All.broadcastMessage方法把該消息廣播給所有客戶端。
Send方法演示了幾個Hub概念:
在hub上聲明一些公共方法,以便客戶端可以調用它們。
使用Microsoft.AspNet.SignalR.Hub。客戶端動態屬性用于與連接到此中心的所有客戶端進行通信。
調用客戶機上的函數(如broadcastMessage函數)來更新客戶機。
在Solution Explorer中,右擊項目,然后添加一個名為Startup的OWIN 啟動類,然后輸入下面這段代碼。
using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(WebApplication2.Startup))] namespace WebApplication2 { public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } } }
在項目中添加一個靜態網頁文件,并命名為index.html,然后右擊該網頁文件,并選擇Set As Start Page,在Index.html中輸入下面的代碼,注意引用正確的文件名。
<!DOCTYPE html> <html> <head> <title>SignalR Simple Chat</title> <style type="text/css"> .container { background-color: #99CCFF; border: thick solid #808080; padding: 20px; margin: 20px; } </style> </head> <body> <div class="container"> <input type="text" id="message" /> <input type="button" id="sendmessage" value="Send" /> <input type="hidden" id="displayname" /> <ul id="discussion"></ul> </div> Reference the jQuery library. <script src="Scripts/jquery-1.12.4.js"></script> Reference the SignalR library. <script src="Scripts/jquery.signalR-2.4.1.js"></script> Reference the autogenerated SignalR hub script. <script src="signalr/hubs"></script> Add script to update the page and send messages. <script type="text/javascript"> $(function () { // 1、聲明一個代理,用于引用服務端hub var chat = $.connection.chatHub; // 2、創建一個回調函數,讓Hub調用它來廣播消息。 chat.client.broadcastMessage = function (name, message) { // Html編碼形式顯示名稱和消息 var encodedName = $(' ').text(name).html(); var encodedMsg = $(' ').text(message).html();; // 將消息添加到頁面。 $('#discussion').append(' ' + encodedName + ': ' + encodedMsg + ' '); }; // 獲取用戶名 $('#displayname').val(prompt('Enter your name:', '')); // 將初始焦點設置為消息輸入框。 $('#message').focus(); // 3、開始連接和發送消息 $.connection.hub.start().done(function () { $('#sendmessage').click(function () { // 在Hub上調用Send方法. chat.server.send($('#displayname').val(), $('#message').val()); // 清除文本框并為下一個注釋重置焦點。 $('#message').val('').focus(); }); }); }); </script> </body> </html>
客戶端通過jquery.signalR.js和signalr/hubs來與服務器進行通信,首先它要聲明一個代理來引用集線器。
var chat = $.connection.chatHub
請注意:在JavaScript中,對服務器類及其成員的引用必須是camelCase形式。本例中將C#服務端的ChatHub類在JavaScript中的引用為chatHub。
然后它要再定義一個回調函數,這個回調函數主要是為了讓服務器進行調用,從而將數據推送到客戶端。
chat.client.broadcastMessage = function (name, message) { //TODO:接收服務器推送的消息 };
而下面的代碼則是為了確保在將消息發送到服務器之前已經與服務器建立了連接。.done 函數表示連接成功后為發送的按鈕綁定一個單擊事件。
// 與服務器建立連接后才能發送消息到服務器 $.connection.hub.start().done(function () { $('#sendmessage').click(function () { // 調用服務器端的ChatHub.Send方法,把消息發送到服務器 chat.server.send("name", "message"); }); });
保存項目,并按F5運行,就可以實現B/S模式下的即時通訊。
項目運行起來后,同時用多個瀏覽器打開的,輸入各自的姓名之后,就能夠實現即時通訊了。回到我們的vs,還能夠看到自動生成的hubs腳本文件,如下圖所示。
三個不同的瀏覽器中的運行方式。 當 Tom、 Anand 和 Susan 發送消息時,所有瀏覽器實時更新:
在ServerHub重寫一個 OnConnected 方法來監控客戶端的連接情況,程序運行的時候web頁面就使用$.connection.hub.start() 與signalR服務開始建立連接了,在調試的時候可以在輸入中看到 "客戶端連接成功!"
public override Task OnConnected() { System.Diagnostics.Trace.WriteLine("客戶端連接成功!"); return base.OnConnected(); }
Clients.Client(connectionId).addMessage() 此方法的作用就是客戶端注冊addMessage方法,向指定連接Id的客戶端發送消息。一對一的聊天發送的消息也必須回發給自己,所以連接的Id可以通過Context.ConnectionId來獲取。當然不用Client.Client(Context.ConnectionId) ,也可以使用Client.Caller()方法直接發送。
Client.Clients(IList connectionIds) 這個方法的意思就是想一組string 的幾個ConnectionId發送消息。類似于QQ上@好友的那種功能。
using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; namespace WebApplication2 { [HubName("UserHub")] public class UserHub : Hub { #region 字段 public static List users = new List(); #endregion 字段 #region 方法 //獲取所有用戶在線列表 private void GetUsers() { var list = users.Select(s => new { s.Name, s.ConnectionID }).ToList(); string jsonList = JsonConvert.SerializeObject(list); Clients.All.getUsers(jsonList); } //登記名字 public void LoginIn(string name) { //查詢用戶 var user = users.SingleOrDefault(u => u.ConnectionID == Context.ConnectionId); if (user != null) { user.Name = name;//登記名字 Clients.Client(Context.ConnectionId).showId(Context.ConnectionId); } GetUsers(); } //發送消息 [HubMethodName("sendMessage")] public void SendMessage(string connectionId, string message) { Clients.All.hello(); var user = users.Where(s => s.ConnectionID == connectionId).FirstOrDefault(); if (user != null) { Clients.Client(connectionId).addMessage(message + "" + DateTime.Now, Context.ConnectionId); //給自己發送,把用戶的ID傳給自己 Clients.Client(Context.ConnectionId).addMessage(message + "" + DateTime.Now, connectionId); } else { Clients.Client(Context.ConnectionId).showMessage("該用戶已離線"); } } /// /// 重寫連接事件 /// /// public override Task OnConnected() { //查詢用戶 var user = users.Where(w => w.ConnectionID == Context.ConnectionId).SingleOrDefault(); //判斷用戶是否存在,否則添加集合 if (user == null) { user = new User("", Context.ConnectionId); users.Add(user); } return base.OnConnected(); } public override Task OnDisconnected(bool stopCalled) { var user = users.Where(p => p.ConnectionID == Context.ConnectionId).FirstOrDefault(); //判斷用戶是否存在,存在則刪除 if (user != null) { //刪除用戶 users.Remove(user); } GetUsers();//獲取所有用戶的列表 return base.OnDisconnected(stopCalled); } #endregion 方法 } public class User { #region 構造函數 public User(string name, string connectionId) { this.Name = name; this.ConnectionID = connectionId; } #endregion 構造函數 #region 屬性 [Key] public string ConnectionID { get; set; } public string Name { get; set; } #endregion 屬性 } }
到此,相信大家對“Asp.net如何通過SignalR2進行實時聊天”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。