如何通过SignalR将消息发送给特定用户(身份标识)?

时间:2017-10-06 19:14:58

标签: asp.net signalr

在我的Startup.Auth.cs

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 Controller操作(与网格更新相关的Put)中:

[...]
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

的实施

但是,我注意到在我的情况下,传递给User方法的IRequest对象的GetUserId属性始终设置为null ...

1 个答案:

答案 0 :(得分:0)

实际上已经解决了另一个问题,就在这里:https://stackoverflow.com/a/22028296/4636721

问题在于Startup.Auth.cs中的初始化顺序: 必须在Cookie之后初始化SignalR并且OwinContext初始化(例如传递给IUserIdProvider的{​​{1}}收到包含非空GlobalHost.DependencyResolver.Register的{​​{1}} IRequest方法:

User

使用下面的GetUserId,我明确声明我想要使用UserId而不是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所给出的UserName:

IUserIdProvider