首页 > 解决方案 > SignalR 是否应该在自己的微服务中

问题描述

我正在创建一个 ASP.NET Core 5 Web API,目前 API 中有 SignalR。将它放在自己的微服务中并让它与 API 通信是更好的做法吗?我相信这对于 SignalR 的可扩展性来说是一个更充分的解决方案。

请提供任何具有正确架构方法的示例项目。

标签: asp.net-web-apiarchitecturesignalrasp.net-core-signalr

解决方案


是的,我会说创建服务是等待。下面是我的实现:

第 0 步:可选择使用 Hub 函数创建字典以确保类型安全

public static class HubFunctionStrings
{
    public const string SendNotification = "Notification";
}

public static class Constants
{
    public const string MyMessageHub = "/MyMessageHub";
}

第 1 步:为其创建一个集线器连接和一个接口。

// The actual Registed
public class MyMessageHub : Hub<IMyMessageHub>
{

    [HubMethodName(HubFunctionStrings.SendNotification)]
    public async Task Message(string message, string lot = "")
    {
        await Clients.All.SendMessageAsync(message, lot);
    }
}

public interface IMyMessageHub
{

    /// <summary>
    /// Send a Notice to all the pages with Notification capabilities
    /// </summary>
    /// <param name="message"></param>
    /// <param name="lot"></param>
    /// <returns></returns>
    [HubMethodName(HubFunctionStrings.SendNotification)]
    Task SendMessageAsync(string message, string lot = "");
    
}

第 2 步:注册集线器

app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapHub<MyMessageHub>(Constants.MyMessageHub);
        endpoints.MapFallbackToPage("/_Host");
    });

第 3 步:创建服务和接口以调用 Hub

// Service itself
public class SignalRService : ISignalRService
{
    #region Private Variables

    private IHubContext<MyMessageHub, IMyMessageHub> MyMessageHub { get; }

    #endregion Private Variables

    /// <summary>
    /// Constructor
    /// </summary>
    public SignalRService(IHubContext<MyMessageHub, IMyMessageHub> MyMessageHub)
    {
        // Create the connection hub connection
        MyMessageHub = MyMessageHub;
    }

    /// <summary>
    /// Send a message
    /// </summary>
    /// <param name="message"></paramm >
    public async Task SendNotificatinAsync(string message, string lot = "") =>
        await MyMessageHub.Clients.All.SendMessageAsync(message, lot);
        
}

// Interface for the service
public interface ISignalRService
{
    /// <summary>
    /// Send a notificaiton
    /// </summary>
    /// <param name="message"></param>
    /// <param name="lot"></param>
    /// <returns></returns>
    Task SendNotificatinAsync(string message, string lot = "");
}

第四步:注册服务

// Add to Startup.cs
services.AddScoped<ISignalRService, SignalRService>()

第 5 步:API 的用法:

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{

    private ISignalRService SignalRService { get; }

    public TestController(ISignalRService signalRService)
    {
        SignalRService = signalRService;
    }
    
    /// <summary>
    /// Send a notification
    /// </summary>
    /// <param name="message"></param>
    /// <param name="lot"></param>
    [HttpGet("SendNotification")]
    public async Task SendNotificationAsync(string message, string lot = "") =>
        await SignalRService.SendNotificatinAsync(message, lot);
}

推荐阅读