2016-07-26 85 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 –