My Github

Blazor学习之旅(11)简易SignalR聊天室

大家好,我是Edison。

很久没有更新Blazor这个系列了,在上一篇我们学习了如何实现多语言和本地化,这一篇我们了解下Blazor+SignalR结合。

什么是SignalR?

ASP.NET Core SignalR 是一个开放源代码库,可用于简化向应用添加实时 Web 功能。实时 Web 功能使服务器端代码能够将内容推送到客户端。适合 SignalR 的候选项:

  • 需要从服务器进行高频率更新的应用。示例包括游戏、社交网络、投票、拍卖、地图和 GPS 应用。
  • 仪表板和监视应用。示例包括公司仪表板、即时销售更新或旅行警报。
  • 协作应用。协作应用的示例包括白板应用和团队会议软件。
  • 需要通知的应用。社交网络、电子邮件、聊天、游戏、旅行警报和很多其他应用都需使用通知。

接下来,我就以一个简易的SignalR实现的聊天室为例,介绍如何通过结合Blazor+SignalR来做一个超快速实现的实时应用。

在Blazor中实现本地化的步骤

(1)准备工作

假设我们已经有了一个Blazor Server应用程序,你可以从这里获取Code:https://github.com/Coder-EdisonZhou/BlazorSamples。

(2)添加SignalR客户端

在项目的Nuget管理器中搜索并安装:Microsoft.AspNetCore.SignalR.Client

这里选择的是6.0.20版本,你需要选择与你的应用框架匹配的版本。

(3)添加SignalR Hub(集线器)

添加一个Hubs目录,在该目录下可以存放我们自定义的多个SignalR Hub。这里我们添加一个 MyChatHub,其代码如下:

using Microsoft.AspNetCore.SignalR;

namespace EDT.BlazorServer.App.Hubs;
public class MyChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

(4)为SignalR添加必要服务

为了SignalR的正常使用,我们需要在Program.cs中做一些必要服务的添加,比如响应压缩中间件(ResponseCompression) 和 EndPoint。

......
using Microsoft.AspNetCore.ResponseCompression;
using EDT.BlazorServer.App.Hubs;
// Add  Response Compression for SignalR
builder.Services.AddResponseCompression(opts =>
{
    opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
          new[] { "application/octet-stream" });
});
......
app.MapBlazorHub();
app.MapHub<MyChatHub>("/mychathub"); // Add Map for SignalR Hubs
app.UseResponseCompression(); // Use Response Compression for SignalR
......

(5)创建聊天室Razor组件页面

在Pages目录下新建一个Razor组件,暂且命名为 ChatRoom.razor。

@page "/chatroom"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>My ChatRoom</PageTitle>

<div class="form-group">
  <label>
    User:
    <input @bind="userInput" />
  </label>
</div>
<div class="form-group">
  <label>
    Message:
    <input @bind="messageInput" size="50" @onkeypress="Enter" />
  </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
  @foreach (var message in messages)
  {
    <li>@message</li>
  }
</ul>

@code {
  private HubConnection? hubConnection;
  private List<string> messages = new List<string>();
  private string? userInput;
  private string? messageInput;

  protected override async Task OnInitializedAsync()
  {
    hubConnection = new HubConnectionBuilder()
      .WithUrl(Navigation.ToAbsoluteUri("/mychathub"))
      .Build();

    hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
    {
      var encodedMsg = $"{user}: {message}";
      messages.Add(encodedMsg);
      InvokeAsync(StateHasChanged);
    });

    await hubConnection.StartAsync();
  }

  private async Task Send()
  {
    if (hubConnection is not null)
    {
      await hubConnection.SendAsync("SendMessage", userInput, messageInput);
    }
  }

  private async Task Enter(KeyboardEventArgs e)
  {
    if (e.Code == "Enter" || e.Code == "NumpadEnter")
    {
      await this.Send();
    }
  }

  public bool IsConnected =>
    hubConnection?.State == HubConnectionState.Connected;

  public async ValueTask DisposeAsync()
  {
    if (hubConnection is not null)
    {
      await hubConnection.DisposeAsync();
    }
  }
}

(6)效果演示

如下图所示,用浏览器打开两个ChatRoom,输入用户名和消息点击Send按钮,既可有一个实时聊天室的效果:

小结

本篇,我们在Blazor中结合SignalR实现了一个超简单的聊天室效果,虽然只是一个很简单的聊天室,但却可以通过SignalR这种方式快速的实现类似的实时应用。

参考代码

GitHub:https://github.com/EdisonChou/BlazorSamples/tree/main

参考资料

Microsoft Learning,《结合使用ASP.NET Core SignalR 和 Blazor

 

 

posted @ 2023-09-12 21:06  EdisonZhou  阅读(561)  评论(0编辑  收藏  举报