Search code examples
asp.net-core.net-coresignalrasp.net-core-webapisignalr-hub

SignalR HubContext send to one client only


Is there a possibility to send a SignalR notification to one client only via IHubContext<>? I have an API with JWT. I got a PostsController that persists some "posts" to a database. What I'd like to achieve is send a notification to all followers of the post creator after the post gets added to the database. I know I could kind of do it by invoking a HubConnection on my JS / Xamarin app, but is there a possibility to do it through IHubContext<>?

    [Route("api/posts")]
    [ApiController]
    public class PostsController : ControllerBase
    {
        private readonly IHubContext<MyHub> _hubContext;
        private readonly IMyService _myService;
        private readonly IUserService _userService;

        public PostsController(
            IHubContext<MyHub> hubContext,
            IMyService myService,
            IUserService userService
            )
        {
            _hubContext= hubContext;
            _myService = myService;
            _userService = userService;
        }

        [HttpPost]
        [Authorize]
        public IActionResult Callback([FromBody] Post post)
        {
            _myService.Insert(post);
            var followers = _userService.GetFollowers(post.UserId);

            foreach (var item in followers)
                  //_hubContext.Client...

            return Ok();
        }
    }

Solution

  • Yes, you can use the hub context to send messages to all clients directly:

    _hubContext.Clients.All.SendAsync("ClientSideHubMethodName");
    

    More detailed information: https://learn.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-3.1

    You can use the SignalR concept of Groups to send a message to all of the followers of the post creator. The summary is that you have to add the user to the desired group every time they connect to the hub.

    public async Task AddToGroup(string groupName)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
        await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has joined the group {groupName}.");
    }
    
    public async Task RemoveFromGroup(string groupName)
    {
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
        await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has left the group {groupName}.");
    }
    

    More detailed information: https://learn.microsoft.com/en-us/aspnet/core/signalr/groups?view=aspnetcore-3.1