2016-07-26 14 views
0

signalr 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の休憩サービスと同じ環境からsignalrを実行しています。これが違いを生むかどうかわかりませんし、デフォルトのベアラトークン設定Web APIが使用しています。

答えて

0

onConnectedイベントで接続クライアントのconnectionidに基づいてグループを作成し、接続IDと一致するグループにブロードキャストするほうがはるかに簡単です。つまり、クライアントが切断した場合、再接続したときに単に新しいグループに属しているだけである。もちろん、認証されたユーザーが必要な場合を除きます。

+0

はい、IUserProviderと共に認証トークンを受け入れるために、認証されたユーザーがいなければならず、現在、認証トークンをシグナル接続とカスタムプロバイダーからCookieで渡しています。 – user1790300

+0

また、私はこれを、オンラインの相手や友人から友人へのコミュニケーションなどの他の機能にも拡張する必要があります。認証トークンを使用しているので、オンラインになっている人を正確に判断する方法については混乱しています。誰かがログアウトせずにブラウザを閉じただけでそこに切断があるように見えます。 – user1790300

+0

signalrアプリケーションに認証を追加するためのチュートリアルを見ましたか? http://www.asp.net/signalr/overview/security/hub-authorization –

関連する問題