第12 屆iT邦幫忙鐵人賽系列文章 (Day28)
SignalR是實現即時通訊的框架,如下圖,在Server Hub宣告要給client端呼叫的方法,能傳送即時訊息給已連線的使用者
https://www.pubnub.com/learn/glossary/what-is-signalr/
而透過Azure SignalR 服務,大大簡化使用門檻,很簡單就能建立一個服務,且享有雲端帶來的高拓展性,這篇文章會step by step 實作以下內容
[ ] 建立 Azure SignalR 服務
[ ] 建立 SignalR Server Hub
[ ] 建立 HTML Client 即時呈現訊息
[ ] 建立 .NET Console App 來發送訊息
登入Azure,進入https://portal.azure.com/#create/Microsoft.SignalRGalleryPackage 新增服務
建完後,到key的選單,我們等等需要這個 Connection String
打開 Web Api 專案的 .csproj,加入以下程式碼
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />
</ItemGroup>
用 Nuget 安裝 Microsoft.Azure.SignalR
在 Web Api 專案案右鍵,建立管理使用者密碼,
建立 Azure:SignalR:ConnectionString ,把剛剛的連線字串貼上
Web Api 專案 Startup.cs 的 ConfigureServices 增加 AddSignalR
services.AddSignalR().AddAzureSignalR();
Configure 增加 Hub 的實作
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
endpoints.MapHub<WeddingMessage>("/message");
});
WeddingMessage.cs
之後可以依照自己的需求在此實作方法
public class WeddingMessage : Hub
{
public void SendMessage(string name, string message)
{
Clients.All.SendAsync("SendMessage", name, message);
}
}
簡單幾個步驟就完成 Server Side 的 Hub
本篇繼續使用 Razor Page,但純HTML也是可以的,因為我們會載入SignalR的JavaScript SDK
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@@aspnet/signalr@1.1.0/dist/browser/signalr.min.js"></script>
在JavaScript也蠻容易實作發送訊息及接收訊息
<script>
document.addEventListener('DOMContentLoaded', function () {
// 建立連線
var connection = new signalR.HubConnectionBuilder()
.withUrl('/message') //因為是同個網域,要視情況換成完成Server Hub的URL
.build();
// 開始連線
connection.start()
.then(function () {
connection.send('SendMessage', 'SYSTEM', '連線成功...');
})
.catch(function (error) {
console.error(error.message);
});
bindConnectionMessage(connection);
// 呈現資料到Html
function createMessageEntry(encodedName, encodedMsg) {
var entry = document.createElement('li');
entry.innerHTML = encodedName + ":" + encodedMsg;
return entry;
}
// 監聽接收訊息事件
function bindConnectionMessage(connection) {
connection.on('CallBackMessage', function (name, message) {
if (!message) return;
var encodedName = name;
var encodedMsg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var messageEntry = createMessageEntry(encodedName, encodedMsg);
var messageBox = document.getElementById('messages');
messageBox.appendChild(messageEntry);
messageBox.scrollTop = messageBox.scrollHeight;
});
}
});
</script>
Html 部分
<h2>Kyle's Wedding 留言板</h2>
<ul id="messages">
</ul>
再來我們建立個 Console App 來發送看看
安裝 Microsoft.AspNetCore.SignalR.Client
建立一個 ClientSignalR 來封裝發送
public class ClientSignalR
{
private HubConnection _hub;
public HubConnection Hub { get; }
private string _connectionUrl;
public string ConnectionUrl { get; }
public ClientSignalR()
{
}
public async Task Initialize(string connectionUrl)
{
_connectionUrl = connectionUrl;
_hub = new HubConnectionBuilder()
.WithUrl(_connectionUrl)
.Build();
await _hub.StartAsync();
}
public async Task SendHubMessage(string methodName, string name, string message)
{
await _hub?.InvokeAsync(methodName, name, message);
}
public async Task CloseConnection()
{
await _hub.DisposeAsync();
}
}
Program.cs
static async System.Threading.Tasks.Task Main(string[] args)
{
var hubClient = new ClientSignalR();
await hubClient.Initialize("<Your Server Hub URL>/message");
while (true)
{
Console.WriteLine("Please enter you message:");
var input = Console.ReadLine();
await hubClient.SendHubMessage("SendMessage", "Kyle", input);
}
}
今天這一篇先這樣避免太長,下一篇我們要來美化HTML&跟Chatbot結合
建立 Azure SignalR 服務
https://azure.microsoft.com/zh-tw/services/signalr-service/
建立 SignalR Server Hub
https://docs.microsoft.com/zh-tw/azure/azure-signalr/signalr-quickstart-dotnet-core
建立 HTML Client 即時呈現訊息
https://docs.microsoft.com/zh-tw/azure/azure-signalr/signalr-quickstart-dotnet-core
建立 .NET Console App 來發送訊息
https://daniel-krzyczkowski.github.io/Real-time-data-with-Microsoft-Azure-SignalR-Service/
本篇文章同步發佈於我的 Medium 如果這篇文章對你有幫助,就大力追蹤和拍手鼓掌下去吧 !!