【问题标题】:Publish message to connected clients from Web API through SignalR通过 SignalR 从 Web API 向连接的客户端发布消息
【发布时间】:2022-02-14 14:14:47
【问题描述】:

目前我有我的服务器端 Web 应用程序来创建一个客户端来调用我的 Web API 端点,它将消息适当地发布回 Web 应用程序(客户端)。

我的想法是,是否可以使用 Postman 触发 Web API 端点,然后所有连接的客户端都会收到该任务正在执行的消息。

我的端点

public class DailyPostingController : ControllerBase
{
    private readonly IMapper _mapper;
    private readonly IDailyPostingService _DailyPostingService;
    private readonly ILogger<DailyPostingController> _logger;

    public DailyPostingController(IMapper mapper, 
        IDailyPostingService DailyPostingService, 
        ILogger<DailyPostingController> logger)
    {
        _mapper = mapper;
        _DailyPostingService = DailyPostingService;
        _logger = logger;
    }

    [Authorize(Policy = Permissions.DailyPosting.Execute)]
    [HttpPost("Execute")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<int> Execute(OperatingCentreQueryModel ocQueryModel)
    {
        _logger.LogDebug("Executing Daily posting for date#" 
            + ocQueryModel.ProcessDate.ToString("dd/mmm/yyy"));

        //How to trigger the hub to tell connected clients this process is started?
        var res = await _DailyPostingService.Execute(ocQueryModel);
        //How to trigger the hub to tell connected clients this process was done?
        return res;
    }
}

我的中心

public class NotificationHub : Hub<INotificationHub>
{
    private readonly UsersState _usersState;
    private readonly ProcessState _processState;
    private readonly ILogger<NotificationHub> _logger;

    public NotificationHub(UsersState usersState, ProcessState processState,
        ILogger<NotificationHub> logger)
    {
        _usersState = usersState;
        _processState = processState;
        _logger = logger;
    }

    public async Task SendMessage(string user, string message)
    {
        await Clients.All.ReceiveMessage(user, message);
    }

    public async Task SendMessageToCaller(string user, string message)
    {
        await Clients.Caller.ReceiveMessage(user, message);
    }

    public async Task SendMessageToGroup(string user, string group, string message)
    {
        await Clients.Group(group).ReceiveMessage(user, message);
    }

    public override Task OnConnectedAsync()
    {
        LogDebug($"({Context.ConnectionId}) connected to notification hub.");
        return base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception exception)
    {
        LogDebug($"({Context.ConnectionId}) disconnected to notification hub.");
        _usersState.RemoveConnectionId(Context.ConnectionId,
            async (user) =>
            {
                await RemoveUser(user);
                await RemoveUserProcess(user);
            });

        await base.OnDisconnectedAsync(exception);
    }

    private void LogDebug(string msg)
    {
        _logger.LogDebug("*** " + msg);
    }

【问题讨论】:

    标签: signalr asp.net-core-webapi signal-processing signalr-hub


    【解决方案1】:

    【讨论】:

      【解决方案2】:
      您可以使用 IHubContext 服务从应用中的其他位置发送 SignalR 消息。您只需将其注入您需要使用它的地方。

      为了解决您的问题,我将向 INotificationHub 添加一个新方法:

      public interface INotificationHub
      {
          Task ExcecutingDailyPost(string action);
      }
      

      在需要使用集线器功能的任何地方注入强类型集线器上下文。

      您的端点可能如下所示:

      public class DailyPostingController : ControllerBase
      {
          private readonly IMapper _mapper;
          private readonly IDailyPostingService _DailyPostingService;
          private readonly ILogger<DailyPostingController> _logger;
          private readonly IHubContext<NotificationHub, INotificationHub> _hubContext;
      
          public DailyPostingController(IMapper mapper, 
              IDailyPostingService DailyPostingService, 
              ILogger<DailyPostingController> logger,
              IHubContext<NotificationHub, INotificationHub> hubContext)
          {
              _mapper = mapper;
              _DailyPostingService = DailyPostingService;
              _logger = logger;
              _hubContext = hubContext;
          }
      
          [Authorize(Policy = Permissions.DailyPosting.Execute)]
          [HttpPost("Execute")]
          [ProducesResponseType(StatusCodes.Status200OK)]
          [ProducesResponseType(StatusCodes.Status400BadRequest)]
          public async Task<int> Execute(OperatingCentreQueryModel ocQueryModel)
          {
              _logger.LogDebug("Executing Daily posting for date#" 
                  + ocQueryModel.ProcessDate.ToString("dd/mmm/yyy"));
              
              // Notify your clients that the process has started
              await _hubContext.Clients.All.ExcecutingDailyPost("START");
      
              var res = await _DailyPostingService.Execute(ocQueryModel);
      
              // Notify your clients that the process has ended
              await _hubContext.Clients.All.ExcecutingDailyPost("END");
              return res;
          }
      }
      

      然后在客户端,您需要在“ExcecutingDailyPost”频道上收听,并根据操作,做您想做的事。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-22
        • 2020-08-13
        • 2015-03-03
        • 1970-01-01
        • 2016-09-19
        • 1970-01-01
        相关资源
        最近更新 更多