C# 通过客户端向特定客户端发送数据';s带信号器的Windows用户名

C# 通过客户端向特定客户端发送数据';s带信号器的Windows用户名,c#,signalr,windows-authentication,C#,Signalr,Windows Authentication,我有一个类似于桌面的web应用程序,带有可拖动的项目,在每个项目拖放时,db都会用新的序列化数据进行更新。现在,每当一个用户改变他的布局,他所有登录的计算机都应该实时更新 如何仅向具有此属性的用户发送数据: User.Identity.Name 基本上应该是这样的: this.Clients.WithWindowsName("windowsusername").sendData(data); 首先,您需要将windows名称发送到服务器。最快的方法是将其作为头从客户端发送,因为它将包含在St

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

如何仅向具有此属性的用户发送数据:

User.Identity.Name
基本上应该是这样的:

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

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

客户端

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

_connection = new HubConnection(_uri);
_connection.Headers.Add("windowsName", "John");
await _connection.Start();
“windowsName”标题将成为您的身份。要确保SignalR将该头识别为标识,您需要创建一个
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”匹配,但您甚至不需要它,如下所述

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

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

    return base.OnConnected();
}
这将创建一个名为Windows计算机的信号器组。 如果用户使用其他计算机登录,他将被添加到同一组。 您不需要删除已断开连接的
中的任何内容,因为信号器将为您处理

组非常方便,因为无论何时向组发送消息,都会通知所有连接的计算机:

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

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

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

客户端

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

_connection = new HubConnection(_uri);
_connection.Headers.Add("windowsName", "John");
await _connection.Start();
“windowsName”标题将成为您的身份。要确保SignalR将该头识别为标识,您需要创建一个
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”匹配,但您甚至不需要它,如下所述

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

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

    return base.OnConnected();
}
这将创建一个名为Windows计算机的信号器组。 如果用户使用其他计算机登录,他将被添加到同一组。 您不需要删除已断开连接的
中的任何内容,因为信号器将为您处理

组非常方便,因为无论何时向组发送消息,都会通知所有连接的计算机:

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

因此,即使是为单个用户(从多台机器连接)创建一个组也很好。

这非常有用!非常感谢你给出了这个令人惊讶的答案和一个非常容易理解的解释!你好!这是非常有用的!非常感谢你给出了这个令人惊讶的答案和一个非常容易理解的解释!你好!