我使用SignalR& amp;的WebAPI。我有一个基于令牌的自定义授权上下文,我使用QueryString为每个SignalR请求提供。
我已经实施了IUserIdProvider
,以便从令牌中检索我的用户。
最后,我想从服务器调用客户端方法,对于特定用户(具有ID),我使用GlobalHost.ConnectionManager
中的HubContext。
我的问题是我的用户永远不会从我的HubContext中找到,但它来自Hub本身......
这是我的IUserIdProvider实现
public class SignalRUserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
var token = request.QueryString["token"];
var scope = GetUnprotectedScope(token);
if (scope == null)
return null;
return scope.Id_User.ToString();
}
}
这是我的Hub imlementation
[HubName("notifier")]
public class NotifierHub : Hub
{
public void Notify(string message)
{
Clients.User("1").Notify(message); //When call from a client, this works very well, only the User with the Id = 1 receive the notification
}
}
最后,我用它从我的服务器调用客户端方法:
GlobalHost
.ConnectionManager
.GetHubContext<NotifierHub>()
.Clients
.User("1")
.Notify(notification.Message);
// This does nothing...
我现在没有解决问题,我不明白会发生什么,有没有人已经实现了这个目标?
答案 0 :(得分:1)
我终于想出了这个问题,但我不知道如何修复它......
实际问题很简单,Hub
本身与客户端和所有内容都有良好的上下文,但GlobalHost.ConnectionManager
没有任何内容。
如果我将我的Hub改为这样的话:
[HubName("notifier")]
public class NotifierHub : Hub
{
public void Notify(string message)
{
Clients.User("1").Notify(message + " from Hub itself");
GlobalHost
.ConnectionManager
.GetHubContext<NotifierHub>()
.Clients
.User("1")
.Notify(message + " from ConnectionManager");
}
}
我的客户收到&#34;来自Hub本身的消息&#34;,但从未收到来自ConnectionManager&#34;我的消息。
总之,我的DependencyInjection有问题......我使用的是Structuremap,这个DependencyResover:
public class StructureMapSignalRDependencyResolver : DefaultDependencyResolver
{
private IContainer _container;
public StructureMapSignalRDependencyResolver(IContainer container)
{
_container = container;
}
public override object GetService(Type serviceType)
{
if (serviceType == null)
return null;
var service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
if (service != null) return service;
return (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
? _container.GetInstance(serviceType)
: _container.TryGetInstance(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
var objects = _container.GetAllInstances(serviceType).Cast<object>();
return objects.Concat(base.GetServices(serviceType));
}
}
我的启动文件:
public void Configuration(IAppBuilder app)
{
app.Map("/signalr", RegisterSignalR);
}
public static void RegisterSignalR(IAppBuilder map)
{
var resolver = new StructureMapSignalRDependencyResolver(IoC.Initialize());
var config = new HubConfiguration { Resolver = resolver };
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR(config);
}
最后我的注册表......
For<Microsoft.AspNet.SignalR.IDependencyResolver>().Add<StructureMapSignalRDependencyResolver>();
For<INotifier>().Use<SignalRNotifier>();