SignalR第一节-在5分钟内完成通信连接和消息发送
前言
首先聲明,這又是一個(gè)小白從入門(mén)到進(jìn)階系列。 SignalR 這個(gè)項(xiàng)目我關(guān)注了很長(zhǎng)時(shí)間,中間好像還看到過(guò)微軟即將放棄該項(xiàng)目的消息,然后我也就沒(méi)有持續(xù)關(guān)注了,目前的我項(xiàng)目中使用的是自己搭建的 WebSocket ,連接管理和消息推送都是統(tǒng)一維護(hù);前段時(shí)間編寫(xiě)了 Asp.NETCore 輕松學(xué)系列,現(xiàn)在騰出了一點(diǎn)時(shí)間,抱著學(xué)習(xí)的心態(tài),想把自己學(xué)習(xí) SignalR 的過(guò)程寫(xiě)出來(lái),就當(dāng)筆記吧,再做筆記的過(guò)程中再加入實(shí)際的項(xiàng)目需求,一步一步的深入學(xué)習(xí) SignalR ,正所謂技多不壓身吧。有想要一起學(xué)習(xí)的同學(xué),可以關(guān)注我,大家一起學(xué)習(xí),一起進(jìn)步。
SignalR 簡(jiǎn)單介紹
根據(jù)官方文檔介紹,SignalR 是一個(gè)面向開(kāi)發(fā)人員的庫(kù),其本質(zhì)是對(duì) Web實(shí)時(shí)連接(WebSocket) 的抽象和封裝,使用 SIgnalR,可以避免自己編寫(xiě)和管理Web實(shí)時(shí)連接,并獲得更多客戶端的兼容性,截止本文發(fā)文為止,SignalR npm 包的版本是 @aspnet/signalr-1.1.2,在 Asp.NETCore 中,SignalR 不支持自動(dòng)重連,如果客戶端連接斷開(kāi),必須顯示重連。話不多說(shuō),下面就開(kāi)始干吧。
1.項(xiàng)目搭建
1.1 搭建 Asp.NETCore 項(xiàng)目基架
本 SignalR 示例基于 .NETCore-2.2 ,所以,我們還是先搭建一個(gè)簡(jiǎn)單的 Asp.NETCore WebApplication
選擇 .NETCore-2.2 ,取消 Https 選擇,因?yàn)槿绻x擇 Https 還需要安裝測(cè)試證書(shū),為了時(shí)間,就別勾選了。
項(xiàng)目創(chuàng)建完成,什么也別做,按下 F5 運(yùn)行網(wǎng)站,看到如下界面
好的,運(yùn)行沒(méi)有問(wèn)題,我們現(xiàn)在先停止網(wǎng)站,做一些簡(jiǎn)單的編碼工作
1.2 引用 SignalR for JavaScript 客戶端 SDK
由于 .NETCore 內(nèi)置了 SignalR 組件,我們無(wú)需額外引用服務(wù)組件,但是需要手動(dòng)添加 SignalR JavaScript 客戶端 SDK,按下圖指示添加客戶端引用:
在彈出的對(duì)話框中輸入 @aspnet/signalr@1.1.2 并選擇“選擇特定文件”選項(xiàng),手動(dòng)選擇兩個(gè)文件 signalr.js/signalr.min.js,注意不要選擇默認(rèn),否則安裝全部組件太浪費(fèi)時(shí)間,對(duì)話框中“目標(biāo)位置”就是 signalr.js/signalr.min.js 的安裝位置,默認(rèn)為 @aspnet/signalr,這里需要手動(dòng)改成 /lib/signalr/xxx 下面
耐心等待幾秒后安裝完成...
2. 編寫(xiě)通訊業(yè)務(wù)邏輯
為了實(shí)現(xiàn)一個(gè)簡(jiǎn)單的群發(fā)通訊過(guò)程,我們需要分別編寫(xiě)服務(wù)器和客戶端的代碼,值得慶幸的是,這些代碼非常簡(jiǎn)單,服務(wù)器和客戶端的代碼一共不到 100 行。
2.1 編寫(xiě)服務(wù)端代碼
服務(wù)器端的代碼如下,創(chuàng)建一個(gè) 類 WeChatHub 繼承自 Hub 類即可,為了方便演示,我還重寫(xiě)了 Hub 的兩個(gè)方法 OnConnectedAsync(連接)/OnDisconnectedAsync(斷開(kāi))
public class WeChatHub : Hub
{
public void Send(MessageBody body)
{
Clients.All.SendAsync("Recv", body);
}
public override Task OnConnectedAsync()
{
Console.WriteLine("哇,有人進(jìn)來(lái)了:{0}", this.Context.ConnectionId);
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
Console.WriteLine("靠,有人跑路了:{0}", this.Context.ConnectionId);
return base.OnDisconnectedAsync(exception);
}
}
public class MessageBody
{
public int Type { get; set; }
public string UserName { get; set; }
public string Content { get; set; }
}
上面這段代碼非常簡(jiǎn)單,WeChatHub 類 只有一個(gè)方法 Send,表示消息入口,其參數(shù)接收一個(gè)實(shí)體類 MessageBody ,這種寫(xiě)法非常有用,后續(xù)文章會(huì)介紹;現(xiàn)在,先讓我們集中精力完成一個(gè)群發(fā)通信。
2.2 配置 SignalR ,進(jìn)行依賴注入
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
...
}
2.3 配置 SignalR 路由地址
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSignalR(routes =>
{
routes.MapHub<WeChatHub>("/wechatHub");
});
...
}
到這里,服務(wù)器基架已搭建完成
2.4 編寫(xiě)客戶端代碼
為了在 Web 瀏覽器中使用 SignalR,我們編寫(xiě)了一小段 js 代碼到文件 wechat.js,并將其和 signalr.js 引入到 Html 頁(yè)面中,客戶端 wechat.js 代碼如下:
"use strict";
var connection = new signalR.HubConnectionBuilder()
.withUrl("/wechatHub")
.build();
connection.on("Recv", function (data) {
var li = document.createElement("li");
li = $(li).text(data.userName + ":" + data.content)
$("#msgList").append(li);
});
connection.start()
.then(function () {
console.log("SignalR 已連接");
}).catch(function(err) {
console.log(err);
});
$(document).ready(function () {
$("#btnSend").on("click", () => {
var userName = $("#userName").val();
var content = $("#content").val();
console.log(userName + ":" + content);
connection.invoke("send", { "Type": 0, "UserName": userName, "Content": content });
});
});
這段代碼需要稍微解釋一下。首先,創(chuàng)建了一個(gè) SignalR 的 connection 對(duì)象,緊接著,馬上使用 connection 綁定了一個(gè)事件,該事件的名稱和服務(wù)器 Send 方法中第一個(gè)參數(shù)的值相呼應(yīng),通過(guò)這種綁定,客戶端就可以接收到服務(wù)器推送過(guò)來(lái)的消息,反之,通過(guò) connection.invoke("send",xxx),也可以將消息發(fā)送到服務(wù)器端的 Send 方法中
3. 測(cè)試消息推送
為了直觀的演示通訊的過(guò)程,我簡(jiǎn)單寫(xiě)了一點(diǎn) Html 樣式代碼(并非我所擅長(zhǎng)),首先我們來(lái)看看 SignalR 的連接過(guò)程,定位到項(xiàng)目根目錄,使用 dotnet run 啟動(dòng)服務(wù),看到如下畫(huà)面:
3.1 啟動(dòng)服務(wù)
3.2 查看 SignalR 連接過(guò)程
輸入網(wǎng)站: http://localhost:5000/ 訪問(wèn)網(wǎng)站,看到如下畫(huà)面紅框處,表示連接成功
看看服務(wù)器的輸出內(nèi)容
3.3 開(kāi)始發(fā)送消息
為了演示消息過(guò)程,我們分別打開(kāi)兩個(gè)瀏覽器窗口,模擬兩個(gè)人在群聊,同時(shí),把他們的消息打印到網(wǎng)頁(yè)上,最終效果圖如下
非常完美,現(xiàn)在所有通過(guò) http://localhost:5000 地址訪問(wèn)該站點(diǎn)的人,都可以同時(shí)收到其它人發(fā)送的消息了。
結(jié)束語(yǔ)
開(kāi)篇已結(jié)束,關(guān)于 SignalR 的原理性內(nèi)容,在開(kāi)篇文章中不會(huì)涉及,快速上手才有興趣深入,這和談戀愛(ài)好像有點(diǎn)不同,逃~;下一篇將在本文的基礎(chǔ)上,加入一些實(shí)際應(yīng)用上的內(nèi)容,最終,完成一個(gè)可以商業(yè)應(yīng)用的例子,本系列的所有代碼都會(huì)托管到 GitHub,歡迎大家下載和 Star,感謝您的點(diǎn)贊!
演示代碼下載
https://github.com/lianggx/Examples/tree/master/SignalR/Ron.SignalRLesson1
總結(jié)
以上是生活随笔為你收集整理的SignalR第一节-在5分钟内完成通信连接和消息发送的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 合肥.NET技术社区首次线下聚会全程回顾
- 下一篇: 尝试:Script Lab,快速 O36