【问题标题】:How to send message to only caller client in SignalR?如何仅向 SignalR 中的调用方客户端发送消息?
【发布时间】:2017-06-16 11:36:34
【问题描述】:

下面是我的 SignalR Hub 类代码。

public class ChatHub : Hub
{
    public void Send(string name, string message)
    {
        // Call the addNewMessageToPage method to update clients.
        Clients.All.addNewMessageToPage(name, message);
    }


    public async void webAPIRequest()
    {
        HttpClient client = new HttpClient();
        HttpResponseMessage response = await client.GetAsync("https://jsonplaceholder.typicode.com/posts");
        //Clients.All.addWebAPIResponseToPage(response);
        Clients.Caller.addWebAPIResponseToPage(response);

        await Task.Delay(1000);

        response = await client.GetAsync("http://www.google.com");

        Clients.Caller.addWebAPIResponseToPage(response);
        //Clients.All.addWebAPIResponseToPage(response);

        await Task.Delay(1000);

        response = await client.GetAsync("https://jsonplaceholder.typicode.com/posts?userId=1");
        //Clients.All.addWebAPIResponseToPage(response);
        Clients.Caller.addWebAPIResponseToPage(response);

    }

}

据我了解,

Clients.Caller.addWebAPIResponseToPage(response);

只向调用者客户端发送消息,而

Clients.All.addWebAPIResponseToPage(response);

将消息发送给所有客户端。

  1. 我的理解正确吗?

  2. 如果否,则需要调用什么方法才能仅向调用方客户端发送消息。

【问题讨论】:

    标签: signalr


    【解决方案1】:

    是的,您的理解是正确的。在这里阅读 https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server#selectingclients

    您可以使用呼叫者,您可以提供当前用户连接 ID 并向其发送消息,或者我在某些地方看到一个名为 self 的组,它可以让用户从各种设备登录并向其发送消息。

    例如,如果您同时在台式机和移动设备上登录,那么您将有两个连接 ID,但您是同一用户。您可以将此用户添加到 self_username_unique_group_name 类型的组,然后向该组发送一条消息,该消息将发送到用户连接的所有设备。

    您还可以在单​​独的表中管理单个用户的连接 ID,并根据需要向所有这些连接 ID 发送消息。

    太多的灵活性和魔力 享受

    【讨论】:

      【解决方案2】:

      我发现这在 https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections 中描述 ConnectionMapping 的地方工作得很好

      public class Startup
      {
          public void ConfigureServices(IServiceCollection services)
          {
              services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
              services.AddScoped<SomeService>();
              services.AddScoped<SessionService>();
              services.AddScoped<ProgressHub>();
          }
      }
      
      public class SomeService 
      {
          ProgressHub _hub;
      
          public SomeService(ProgressHub hub)
          {
              _hub = hub;
          }
      
          private async Task UpdateProgressT(T value)
          {
              _hub.Send(value);
          }
      }
      
      
      
      public class ProgressHub : Hub
      {
          private readonly static ConnectionMapping<string> _connections = new ConnectionMapping<string>();
          private readonly IHubContext<ProgressHub> _context;
          private readonly SessionService _session;
      
          public ProgressHub(IHubContext<ProgressHub> context, SessionService session)
          {
              _context = context;
              _session = session;
          }
      
          public override Task OnConnectedAsync()
          {            
              _connections.Add(_session.SiteId, Context.ConnectionId);
      
              return base.OnConnectedAsync();
          }
      
          public override Task OnDisconnectedAsync(Exception exception)
          {            
              _connections.Remove(_session.SiteId, Context.ConnectionId);
      
              return base.OnDisconnectedAsync(exception);
          }        
              
          public async Task Send(object data)
          {            
              foreach (var connectionId in _connections.GetConnections(_session.SiteId))
              {
                  await _context.Clients.Client(connectionId).SendAsync("Message", data);
              }
          }
      }
      
      
      public class SessionService
      {
          private readonly ISession _session;
      
          public SessionService(IHttpContextAccessor accessor)
          {
              _session = accessor.HttpContext.Session;
      
              if (_session == null) throw new ArgumentNullException("session");
          }   
      
          public string SiteId
          {
              get => _session.GetString("SiteId");
              set => _session.SetString("SiteId", value);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-04-16
        • 1970-01-01
        • 1970-01-01
        • 2016-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多