【问题标题】:SignalR send message to specific userSignalR 向特定用户发送消息
【发布时间】:2017-04-07 13:23:51
【问题描述】:

我创建了一个 SignalR 项目。想要一个像基本whatsapp这样的应用程序。我可以使用 SignalR 向所有客户端发送消息,但无法向特定用户发送消息。

这是我尝试过的。

服务器端

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();
    }
}

public class ChatHub : Hub
{
    public static string UserName = "";
    public void Send(string User, string Message)
    {
        //It doesn't works
        Clients.User(UserName).sendMessage(Message);
        //It works
        Clients.All.sendMessage(Message);
    }
    public override Task OnConnected()
    {
        //It works I get the UserName
        UserName = Context.QueryString["UserName"];
        return base.OnConnected();
    }
}

客户端

protected override async void OnAppearing()
{
    chatHubConnection = new HubConnection("http://192.168.2.2:80/", new Dictionary<string, string>{
        { "UserName", myUser }
     });
    chatHubProxy = chatHubConnection.CreateHubProxy("ChatHub");
    chatHubProxy.On<string>("sendMessage", (k) => {
        Messages.Add(string.Format("Msg:{0}", k));
    });
    await chatHubConnection.Start();
}
private async void SendButton_Clicked(object sender, EventArgs e)
{
    await chatHubProxy.Invoke<string>("Send", recieverEntry.Text, messageEntry.Text);
}

【问题讨论】:

  • 但是你的UserName 是静态的,所以它会(假设它可以工作)保存最后一个连接用户的名字,我不认为这是你所期望的。
  • @Evk 是的,我知道,我创建它是为了测试代码。

标签: c# xamarin signalr signalr-hub signalr.client


【解决方案1】:

使用 ConnectionId 向特定客户端发送消息。 UserId 和 UserName 是不同的东西,更多细节 - https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections

将您的代码更改为以下代码(理想情况下,此 Connections 字典应提取为单独的类以处理用户名到连接的映射)

public class ChatHub : Hub
{
    public static ConcurrentDictionary<string, string> Connections = new ConcurrentDictionary<string, string>();
    public void Send(string username, string message)
    {
        string connectionToSendMessage;
        Connections.TryGetValue(username, out connectionToSendMessage);

        if (!string.IsNullOrWhiteSpace(connectionToSendMessage))
        {
            Clients.Client(connectionToSendMessage).SendMessage(message);
        }
    }
    public override Task OnConnected()
    {
        if (!Connections.ContainsKey(Context.ConnectionId))
        {
            Connections.TryAdd(Context.QueryString["UserName"], Context.ConnectionId);
        }

        return base.OnConnected();
    }
}

【讨论】:

  • 感谢您的回复。但最后一个用户不是我要发送消息的用户。
  • @Guest 您可以向任何用户发送消息,但是您需要该用户的 connectionId。您当前代码的问题是,您使用的是用户名。第一个问题,该函数需要 UserId(不是 UserName)。其次,如果您没有 userId,那么您可以在 Client 上使用 ConnectionId
  • @Guest 您可以将您的用户映射到连接。执行此操作的选项docs.microsoft.com/en-us/aspnet/signalr/overview/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 2016-09-19
  • 2017-12-28
  • 2015-04-27
  • 1970-01-01
相关资源
最近更新 更多