2017-10-06 230 views
0

在我Startup.Auth.cs如何通過SignalR將消息發送給特定用戶(身份標識)?

private static void ConfigSignalR(IAppBuilder appBuilder) 
{ 
    appBuilder.MapSignalR(); 
    var idProvider = new PrincipalUserIdProvider(); 
    GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider),() => idProvider); 
} 

UserHub.cs

public class UserHub : Hub 
{ 
} 

在服務器端,在我的API控制器動作之一(與網格更新認沽):

[...] 
var userHub = GlobalHost.ConnectionManager.GetHubContext<UserHub>(); 
// Line below does not work 
// userHub.Clients.User(userId).send("Hi"); 

// But this line below works when sending the message to everybody 
userHub.Clients.All.send("Hi"); 

return Request.CreateResponse(HttpStatusCode.OK); 

在JS View客戶端:

@Request.IsAuthenticated 
{ 
    <script> 

     $(function() { 
      var userHub = $.connection.userHub; 

      console.log(userHub.client); 

      userHub.client.send = function(message) { 
       alert('received: ' + message); 
      }; 

      $.connection.hub.start().done(function() { 
      }); 
     }); 
    </script> 
} 

爲什麼在通過userId時我的客戶端收不到任何東西? (也嘗試通過userName,結果相同)。

[編輯] 技術上實現了正確的方法是充分利用IUserIdProvider執行:

然而,我注意到,在我如果傳遞給GetUserId方法的IRequest對象的User屬性始終設置爲null ...

+1

我的理解是最簡單,最乾淨的方式做到這一點是將客戶端和連接存儲在OnConnected方法內的字典中。用戶基於隨機生成的連接ID,因此您傳遞的任何內容都不會匹配。 – willthiswork89

回答

0

的解決方案實際上已經給出了另外一個問題,就在這裏:https://stackoverflow.com/a/22028296/4636721

的問題是所有關於在Startup.Auth.cs初始化順序: SignalR必須餅乾後進行初始化和OwinContext初始化,如IUserIdProvider傳遞給GlobalHost.DependencyResolver.Register接收包含IRequest一個非空UserGetUserId方法:

public partial class Startup 
{ 
    public void ConfigureAuth(IAppBuilder appBuilder) 
    { 
     // Order matters here... 
     // Otherwise SignalR won't get Identity User information passed to Id Provider... 
     ConfigOwinContext(appBuilder); 
     ConfigCookies(appBuilder); 
     ConfigSignalR(appBuilder); 
    } 

    private static void ConfigOwinContext(IAppBuilder appBuilder) 
    { 
     appBuilder.CreatePerOwinContext(ApplicationDbContext.Create); 
     appBuilder.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
     appBuilder.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); 
     appBuilder.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); 
     appBuilder.CreatePerOwinContext(LdapAdEmailAuthenticator.Create); 
    } 

    private static void ConfigCookies(IAppBuilder appBuilder) 
    { 
     appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      LoginPath = new PathString("/Account/Login"), 
      Provider = new CookieAuthenticationProvider 
      { 
       OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser> 
       (
        TimeSpan.FromHours(4), 
        (manager, user) => user.GenerateUserIdentityAsync(manager) 
       ) 
      } 
     }); 
     appBuilder.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 
     appBuilder.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5)); 
     appBuilder.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie); 
    } 

    private static void ConfigSignalR(IAppBuilder appBuilder) 
    { 
     appBuilder.MapSignalR(); 
     var idProvider = new HubIdentityUserIdProvider(); 
     GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider),() => idProvider); 
    } 
} 

使用IUserIdProvider下面,我明確宣佈,我要使用的用戶ID,而不是用戶名由IUserIdProvider的缺省實現給定,又名PrincipalUserIdProvider

public class HubIdentityUserIdProvider : IUserIdProvider 
{ 
    public string GetUserId(IRequest request) 
    { 
     return request == null 
      ? throw new ArgumentNullException(nameof(request)) 
      : request.User?.Identity?.GetUserId(); 
    } 
} 
相關問題