我有一种类似桌面的Web应用程序,带有可拖动的项目,并且在每个项目拖放时,db都会使用新的序列化数据进行更新。现在,每当一个用户更改其布局时,他所有登录的计算机都应该实时更新。
我如何仅向具有此属性的用户发送数据:
User.Identity.Name
基本上看起来应该是这样的:
this.Clients.WithWindowsName("windowsusername").sendData(data);
答案 0 :(得分:3)
首先,您需要将Windows名称发送到服务器。最快捷的方法是将其作为标题从客户端发送,因为它将包含在Start()
调用中,因此您不需要额外的proxy.Invoke()
:
客户端
_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”,但您甚至不需要它,如下所述。
正如您所说,用户可以从多台计算机登录。处理此问题的最佳方法是创建SignalR组:
public override Task OnConnected()
{
var windowsName = Context.Headers.Get("windowsName");
Groups.Add(Context.ConnectionId, windowsName);
return base.OnConnected();
}
这将创建一个具有Windows机器名称的SignalR组。
如果用户使用其他计算机登录,则会将其添加到同一组中。
你不需要删除OnDisconnected
内的任何内容,因为SignalR会为你处理它。
组非常方便,因为无论何时向组发送消息,都会通知所有连接的计算机:
Clients.Group("John").sendData(data);
Clients.Group(User.Identity.Name).sendData(data);
即使是单个用户(从多台机器连接)也可以创建一个组。