2016-07-26 3 views
0

Я пытаюсь использовать новый поставщик идентификатора пользователя, указанный в signalr 2, для отправки сообщений конкретному пользователю. Когда я вызываю метод Clients.All, я вижу, что это работает, когда код javascript вызывается с сервера, а ui выводит ожидаемый текст для моего тестового примера. Однако, когда я переключаюсь на Client.User, клиентский код никогда не вызывается с сервера. Я выполнил код, описанный в этом примере: SignalR - Sending a message to a specific user using (IUserIdProvider) *NEW 2.0.0*.Отправка сообщения определенному пользователю с помощью signalr

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); 
    } 

} 

Нужно ли мне сопоставлять пользователя с самими подключениями с помощью IUserIdProvider через OnConnected, OnDisconnected и т. Д., Или это происходит автоматически за кулисами? Кто-то ошибается в моем опубликованном коде, что может быть проблемой? Я запускаю signalr из той же среды, что и мои службы api rest, не знаю, имеет ли это значение и использует ли установленный токен токен, используемый api.

ответ

0

Было бы намного проще создать группу на основе connectid подключающегося клиента в событии onConnected и передать в группу, которая соответствует подключенному идентификатору, таким образом, если клиент отключится, когда они снова подклюятся просто принадлежали бы самой новой группе. Если, конечно, вы не должны иметь аутентифицированного пользователя.

+0

Да, у меня должны быть аутентифицированные пользователи, и в настоящее время я использую токены аутентификации, переданные в файлах cookie из соединения signalr, и пользовательский поставщик, чтобы принять токен аутентификации вместе с IUserProvider. – user1790300

+0

Кроме того, мне нужно расширить это на другие возможности, например, определить, кто в сети, друг другу и т. Д. Я как-то смущен тем, как точно определить, кто в сети, поскольку я использую токены аутентификации. Похоже, что там будет отключиться, если кто-то просто закроет свой браузер, не выйдя из системы. – user1790300

+0

Вы изучили учебное пособие для добавления аутентификации в приложения signalr? http://www.asp.net/signalr/overview/security/hub-authorization –

Смежные вопросы