一、SignalR是什么
Asp.net SignalR是微軟為實現實時通信的一個類庫。一般情況下,SignalR會使用JavaScript的長輪詢(long polling)的方式來實現客戶端和服務器通信,隨着Html5中WebSockets出現,SignalR也支持WebSockets通信。另外SignalR開發的程序不僅僅限制於宿主在IIS中,也可以宿主在任何應用程序,包括控制台,客戶端程序和Windows服務等,另外還支持Mono,這意味着它可以實現跨平台部署在Linux環境下。
SignalR內部有兩類對象:
Http持久連接(Persisten Connection)對象:用來解決長時間連接的功能。還可以由客戶端主動向服務器要求數據,而服務器端不需要實現太多細節,只需要處理PersistentConnection 內所提供的五個事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。
Hub(集線器)對象:用來解決實時(realtime)信息交換的功能,服務端可以利用URL來注冊一個或多個Hub,只要連接到這個Hub,就能與所有的客戶端共享發送到服務器上的信息,同時服務端可以調用客戶端的腳本。
SignalR將整個信息的交換封裝起來,客戶端和服務器都是使用JSON來溝通的,在服務端聲明的所有Hub信息,都會生成JavaScript輸出到客戶端,.NET則依賴Proxy來生成代理對象,而Proxy的內部則是將JSON轉換成對象。
二、為什么要用SignalR
聊天室,如在線客服系統,IM系統等
消息的實時推送服務
巡更人員位置的實時推送
1. server -------- 創建一個MVC 項目,選擇新建的項目,右擊-->選擇管理NuGet程序包-->搜索 signalr--> 安裝Microsoft ASP.NET SignalR
新建啟動程序 Startup.cs
在類中添加代碼:
- app.MapSignalR();
在集線器類ChatHub.cs中添加如下代碼
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Web; using Microsoft.AspNet.SignalR; using System.Threading.Tasks; namespace ChatServer { public class ChatHub : Hub { public void Hello() { //Clients.All.hello(); //Clients.All.AddMsg(); } /// <summary> /// 供客戶端調用的服務器端代碼 /// </summary> /// <param name="message"></param> public void Send(string name,string message) { // 調用所有客戶端的sendMessage方法 Clients.All.sendMessage(name, message); Trace.WriteLine("調用所有客戶端的sendMessage方法"); } /// <summary> /// 客戶端連接的時候調用 /// </summary> /// <returns></returns> public override Task OnConnected() { Trace.WriteLine("客戶端連接成功"); return base.OnConnected(); } } }
2. 客戶端(winform)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.AspNet.SignalR.Client; namespace ChatClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); Text = "Test SignalR"; FormClosing += Form1_FormClosing; } public IHubProxy HubProxy { get; set; } const string ServerURI = "https://localhost:44306/";//ServerURI = "https://localhost:44306/signalr"; public HubConnection Connection { get; set; } /// <summary> /// Creates and connects the hub connection and hub proxy. This method /// is called asynchronously /// </summary> private async void ConnectAsync() { Connection = new HubConnection(ServerURI); Connection.Closed += ShowConnectionClosed; HubProxy = Connection.CreateHubProxy("ChatHub"); //Handle incoming event from server: use Invoke to write to console from SignalR's thread HubProxy.On<string, string>("sendMessage", (name, message) => { this.Invoke( new Action(() => { RichTextBoxConsole.AppendText(String.Format("{0}: {1}\r", name, message)); } )); } ); try { await Connection.Start(); } catch (HttpRequestException) { Text = "Unable to connect to server: Start server before connecting clients."; //No connection: Don't enable Send button or show chat UI return; } TextBoxMessage.Focus(); RichTextBoxConsole.AppendText("Connected to server at " + ServerURI + "\r"); } private void CloseConnection() { if (Connection != null) { Connection.Stop(); Connection.Dispose(); } } /// <summary> /// If the server is stopped, the connection will time out after 30 seconds (default), and the /// Closed event will fire. /// </summary> private void ShowConnectionClosed() { RichTextBoxConsole.AppendText("You have been disconnected.\r\n"); } private void btnConnect_Click(object sender, EventArgs e) { RichTextBoxConsole.AppendText("Connecting to server..."); ConnectAsync(); } private void btnSend_Click(object sender, EventArgs e) { if (Connection.State == Microsoft.AspNet.SignalR.Client.ConnectionState.Disconnected) { ShowConnectionClosed(); return; } HubProxy.Invoke("Send", "Client wgscd", TextBoxMessage.Text); TextBoxMessage.Text = String.Empty; TextBoxMessage.Focus(); } private void btnDisconnect_Click(object sender, EventArgs e) { CloseConnection(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { CloseConnection(); } } }