如何在controller中调用hub的方法? SignalR ASP.NET Core

问题描述 投票:0回答:1

如何从 API 控制器调用/调用集线器方法“DisconnectFromConversation”

中心实施

    public class ChatHub : Hub
    {
    private readonly IConversationService \_converstaionService;
    private readonly IMemberService \_converstaionUserService;
    private readonly IMessageService \_messageService;
    
            public ChatHub(IConversationService converstaionService,
                           IMemberService converstaionUserService, IMessageService messageService)
            {
                _converstaionService = converstaionService;
                _converstaionUserService = converstaionUserService;
                _messageService = messageService;
            }
        
           
            public async Task DisconnectFromConversation(Guid conversationId, Guid userId)
            {
                if (ConnectionMapping.TryGetValue(userId, out var connectionIds))
                {
                    
                    foreach (var connectionId in connectionIds)
                    {
                        await Groups.RemoveFromGroupAsync(connectionId,   conversationId.ToString());
                    }
                }
            }

控制器实现

    public class MemberController : ControllerBase
    {
    private readonly IMemberService \_memberService;
    private readonly IConversationService \_conversationService;
    private readonly IHubContext\<ChatHub\> \_hubContext;
    
            public MemberController(IMemberService memberService, IConversationService       conversationService, IHubContext<ChatHub> hubContext)
            {
                _memberService = memberService;
                _conversationService = conversationService;
                _hubContext = hubContext;
            }
        
            [HttpDelete("conversations/{conversationId}")]
            public async Task<IActionResult> DeleteMember([FromBody]string userId, Guid conversationId)
            {
                var test = Request.Headers["connectionId"];
                if (!Request.Headers.ContainsKey("User-Id"))
                {
                    return BadRequest();
                }
                else if (await _conversationService.IsUserCreator(conversationId,
                     new Guid(Request.Headers["User-Id"]))
                     || Request.Headers["User-Id"] == userId.ToString())
                {
                    await _memberService.DeleteMemberAsync(conversationId, new Guid(userId));
                    //await _hubContext.Clients.All
                        .BrodacastMessage("DisconnectFromConversation", conversationId, userId);
                    await _hubContext.Clients.Client(test)
                        .SendAsync("DisconnectFromConversation", conversationId, userId);
                    return NoContent();
                }
                else
                {
                    return Forbid();
                }
            }
        }

我尝试通过下一种方式调用

await _hubContext.Clients.All.BrodacastMessage("DisconnectFromConversation", conversationId, userId);
但在调试模式下,它不会触发集线器方法中的断点 我也试过
await _hubContext.Clients.Client(test).SendAsync("DisconnectFromConversation", conversationId, userId);
我正在考虑将此操作委托给客户端。但不幸的是我没有它(这是任务的要求之一)

asp.net-core asp.net-web-api controller signalr signalr-hub
1个回答
0
投票

使用...

await _hubContext.Clients.All.BrodacastMessage("DisconnectFromConversation", conversationId, userId);

将尝试调用名为“DisconnectFromConversation”的客户端方法。

IHubContext 允许您访问组、客户端等以向客户端发送消息,但不允许您访问在服务端集线器上声明的方法。

将该方法移至服务并将 IHubContext 注入其中,以便您可以访问 IHubContext 组、客户端等,例如:

public class ChatHubService
{
    private readonly IHubContext<ChatHub> _hubContext;

    public ChatService(IHubContext<ChatHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public async Task DisconnectUserFromConversation(Guid conversationId, Guid userId)
    {
        if (ConnectionMapping.TryGetValue(userId, out var connectionIds))
        {
            foreach (var connectionId in connectionIds)
            {
                await _hubContext.Groups.RemoveFromGroupAsync(connectionId, conversationId.ToString());
            }
        }
    }    
}

然后将该服务注入到您的服务器聊天中心和控制器中:

public class ChatHub : Hub
{
    private readonly ChatHubService _chatHubService;

    public ChatHub(ChatHubService chatHubService)
    {
        _chatHubService = chatHubService;
    }

    public async Task DisconnectFromConversation(Guid conversationId, Guid userId)
    {
        await _chatHubService.DisconnectUserFromConversation(conversationId, userId);
    }
}

public class MemberController : ControllerBase
{
    private readonly ChatHubService _chatHubService;

    public MemberController(ChatHubService chatHubService)
    {
        _chatService = chatService;
    }

    [HttpDelete("conversations/{conversationId}")]
    public async Task<IActionResult> DeleteMember([FromBody]string userId, Guid conversationId)
    {
        await _chatHubService.DisconnectUserFromConversation(conversationId, new Guid(userId));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.