ASP.NET SignalR是一個友善程式員添加實時網絡通信功能的類庫。所謂的實時網絡通信功能(Real-time Web Functionality)就是需要伺服器主動推送資料到使用者用戶端,而非伺服器等待使用者用戶端請求資料的功能。以聊天室為例,當一個使用者發送群發消息之後,在所有使用者的聊天視窗中都需要顯示出這條消息,如果每個使用者用戶端都是用Ajax每隔一定時間去伺服器上拉取消息,那樣不僅效率低下并增加伺服器負擔,也不是真正意義上的實時程式。
消息傳輸機制
ASP.Net SignalR使用新的Websocket傳輸協定,他實作了浏覽器和伺服器全雙工通信(允許伺服器主動發消息給用戶端),并相容以前的長連接配接(Long poll)傳輸方式, 是以對于開發人員來說,不需要自己去維護使用何種傳輸方式,SignalR會自動根據用戶端浏覽器的版本自動切換消息傳輸方式
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(ChatRoom.Startup))]
namespace ChatRoom
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
//啟用SignalR
app.MapSignalR();
}
}
}
添加樞紐(Hub)
在工程中添加ChatRoomHub.cs, 選擇SignalR Hub Class(v2)
SignalR學習筆記(一) 簡單聊天室
替換ChatRoomHub類中的内容替換
using Microsoft.AspNet.SignalR;
using System.Collections.Generic;
using System.Linq;
namespace ChatRoom
{
public class ChatRoomHub : Hub
{
private static Dictionary<string, string> _nickNames = new Dictionary<string, string>();
public void SetNickName(string nickName)
{
//當Hub啟動完畢,每個連接配接到這個Hub的用戶端都會自動配置設定一個唯一的ConnectionId。
//當SignalR向指定用戶端推送消息的時候,需要指定ConnectionId, 是以這裡需要記錄一下每個昵稱對應的用戶端ConnectionId
_nickNames.Add(Context.ConnectionId, nickName);
//當使用者設定昵稱之後,需要發送歡迎資訊到所有的使用者用戶端,調用用戶端receiveWelcomeMessage方法顯示歡迎資訊
Clients.All.ReceiveWelcomeMessage($"{nickName}進入聊天室。");
}
public void Send(string nickName, string message)
{
if (string.IsNullOrWhiteSpace(nickName) || string.IsNullOrWhiteSpace(message))
{
//如果使用者昵稱或者消息不存在,就不做任何操作
return;
}
if (message.StartsWith("to") && message.Split(' ').Length == 3)
{
//私聊消息
var toUserName = message.Split(' ')[1];
if (_nickNames.ContainsValue(toUserName))
{
var connectionId = _nickNames.First(p => p.Value == toUserName).Key;
if (!string.IsNullOrWhiteSpace(connectionId) && connectionId != Context.ConnectionId)
{
Clients.Client(connectionId).ReceivePrivateMessage(nickName, message.Split(' ')[2]);
}
}
}
else
{
//普通廣播消息
if (_nickNames.ContainsValue(nickName))
{
Clients.All.ReceiveBroadcastMessage(nickName, message);
}
}
}
}
}