第12 屆iT邦幫忙鐵人賽系列文章 (Day28)

SignalR是實現即時通訊的框架,如下圖,在Server Hub宣告要給client端呼叫的方法,能傳送即時訊息給已連線的使用者

<a href="https://www.pubnub.com/learn/glossary/what-is-signalr/">https://www.pubnub.com/learn/glossary/what-is-signalr/</a> 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 SignalR 服務

登入Azure,進入https://portal.azure.com/#create/Microsoft.SignalRGalleryPackage 新增服務

建完後,到key的選單,我們等等需要這個 Connection String

建立 SignalR Server Hub

打開 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

建立 HTML Client 即時呈現訊息

本篇繼續使用 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>

建立 .NET Console App 來發送訊息

再來我們建立個 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結合

懶人包,本次學到了什麼?