2016-07-26 61 views
0

我想使用信号发送器2中指定的新用户ID提供程序向特定用户发送消息。当我调用Clients.All方法时,我发现这个工作正常,因为我的javascript代码被服务器调用,并且ui为我的测试用例生成了一些预期的文本。但是,当我切换到Clients.User时,客户端代码永远不会从服务器调用。我遵循此示例中列出的代码:SignalR - Sending a message to a specific user using (IUserIdProvider) *NEW 2.0.0*通过信号发送消息给特定的用户

NotificationHub.cs:

public class NotificationHub : Hub 
{ 
    [Authorize] 
    public void NotifyUser(string userId, int message) 
    { 
     Clients.User(userId).DispatchMessage(message); 
    } 

    public override Task OnConnected() 
    { 
     return base.OnConnected(); 
    } 

    public override Task OnDisconnected(bool stopCalled) 
    { 
     return base.OnDisconnected(stopCalled); 
    } 

    public override Task OnReconnected() 
    { 
     return base.OnReconnected(); 
    } 
} 

IUserIdProvider.cs:

public class UserIdProvider : IUserIdProvider 
{ 
    MemberService _memberService; 
    public UserIdProvider() 
    { 
    } 

    public string GetUserId(IRequest request) 
    { 
     long UserId = 0; 

     if (request.User != null && request.User.Identity != null && 
      request.User.Identity.Name != null) 
     { 
      var currenUser = Task.Run(() => _memberService.FindByUserName(request.User.Identity.Name)).Result; 
      UserId = currenUser.UserId; 
     } 

     return UserId.ToString(); 
    } 
} 

Startup.cs

HttpConfiguration config = GlobalConfiguration.Configuration; 

     config.Routes.MapHttpRoute(
      "Default2", 
      "api/{controller}/{action}/{id}", 
      new { id = RouteParameter.Optional }); 

     config.Routes.MapHttpRoute(
      "DefaultApi2", 
      "api/{controller}/{id}", 
      new { id = RouteParameter.Optional }); 

     app.Map("/signalr", map => 
     { 
      map.UseCors(CorsOptions.AllowAll); 

      var idProvider = new UserIdProvider(); 

      GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider),() => idProvider); 

      map.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions() 
      { 
       Provider = new QueryStringOAuthBearerAuthenticationProvider() 
      }); 

      var hubConfiguration = new HubConfiguration 
      { 
      }; 
      map.RunSignalR(hubConfiguration); 
     }); 

     app.MapSignalR(); 

QuerstringOAuthBearerAuthenticationProvider:

public class QueryStringOAuthBearerAuthenticationProvider 
: OAuthBearerAuthenticationProvider 
{ 
    public override Task RequestToken(OAuthRequestTokenContext context) 
    { 
     if (context == null) throw new ArgumentNullException("context"); 

     // try to find bearer token in a cookie 
     // (by default OAuthBearerAuthenticationHandler 
     // only checks Authorization header) 

     var tokenCookie = context.OwinContext.Request.Cookies["BearerToken"]; 
     if (!string.IsNullOrEmpty(tokenCookie)) 
      context.Token = tokenCookie; 
     return Task.FromResult<object>(null); 
    } 

} 

我是否需要通过OnConnected,OnDisconnected等使用IUserIdProvider将用户映射到自己的连接,还是在幕后自动执行?我的发布代码中是否有人可能会出现问题?我正在运行与我的web api rest服务相同的环境中的signalr,不知道这是否有所作为,并使用web api使用的默认持票人令牌设置。

回答

0

根据连接客户端的connectionid,onConnected事件和广播到匹配连接ID的组创建一个组会更容易,这样,如果客户端断开连接,当它们重新连接时会简单地属于一个新的组。除非你需要拥有一个经过认证的用户。

+0

是的,我需要通过身份验证的用户,并且目前正在使用来自信号连接和自定义提供程序的cookie中传递的身份验证令牌,以接受身份验证令牌以及IUserProvider。 – user1790300

+0

此外,我确实需要扩展到其他功能,如确定谁在线,朋友对朋友的沟通等。我很困惑如何准确地确定谁在线,因为我正在使用身份验证令牌。似乎有人会在没有注销的情况下关闭浏览器就会断开连接。 – user1790300

+0

你有没有看过添加认证信号器应用的教程? http://www.asp.net/signalr/overview/security/hub-authorization –