使用 SignalR 通过客户端的 Windows 用户名向特定客户端发送数据

Send data to a specific client by the client's Windows User Name with SignalR

我有一种类似于桌面的 Web 应用程序,带有可拖动的项目,并且在拖放每个项目时,数据库都会使用新的序列化数据进行更新。现在每当一个用户改变他的布局时,他所有登录的计算机都应该实时更新。

我将如何使用此 属性:

将数据仅发送给用户
User.Identity.Name

基本上它应该是这样的:

this.Clients.WithWindowsName("windowsusername").sendData(data);

首先,您需要将windows 名称发送到服务器。最快的方法是将其作为 header 从客户端发送,因为它将包含在 Start() 调用中,因此您不需要额外的 proxy.Invoke():

客户端

_connection = new HubConnection(_uri);
_connection.Headers.Add("windowsName", "John");
await _connection.Start();

服务器端

那"windowsName" header 将是你的身份。为确保 SignalR 将 header 识别为身份,您需要创建 IUserIdProvider:

的实现
using Microsoft.AspNet.SignalR;

namespace YourServer
{
    public class UserIdProvider : IUserIdProvider
    {
        public string GetUserId(IRequest request)
        {
            return request.Headers.Get("windowsName");
        }
    }
}

然后将其插入全局依赖解析器:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var idProvider = new UserIdProvider();
        GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => idProvider);

        // TODO configure signalR here
    }
}

无论何时访问 User.Identity.Name,它都会匹配 "windowsName",但您甚至不需要它,如下所述。

如您所说,一个用户可以从多台计算机登录。处理此问题的最佳方法是创建 SignalR 组:

public override Task OnConnected()
{
    var windowsName = Context.Headers.Get("windowsName");
    Groups.Add(Context.ConnectionId, windowsName);

    return base.OnConnected();
}

这将使用 Windows 机器的名称创建一个 SignalR 组。 如果用户 logs-in 使用其他机器,他将被添加到同一组。 您不需要删除 OnDisconnected 中的任何内容,因为 SignalR 会为您处理。

群组非常方便,因为每当您向群组发送消息时,所有连接的机器都会收到通知:

Clients.Group("John").sendData(data);
Clients.Group(User.Identity.Name).sendData(data);

因此,即使是单个用户(从多台计算机连接)也可以创建一个组。