【问题标题】:Sending a message to a specific user via signalr通过 signalr 向特定用户发送消息
【发布时间】:2016-11-30 11:21:45
【问题描述】:

我正在尝试使用信号器 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);
    }

}

我是否需要自己使用 IUserIdProvider 通过 OnConnected、OnDisconnected 等将用户映射到连接,或者这是否会在幕后自动发生?我发布的代码中是否有人错误也可能是一个问题?我在与我的 web api 休息服务相同的环境中运行 signalr,不知道这是否会有所不同,并使用默认的不记名令牌设置 web api 正在使用。

【问题讨论】:

    标签: signalr asp.net-web-api2


    【解决方案1】:

    在 onConnected 事件中根据连接客户端的 connectionid 创建一个组并广播到与连接的 id 匹配的组,这样如果客户端断开连接,当他们重新连接时,他们会更容易只是属于他们自己的一个新群体。当然,除非您需要经过身份验证的用户。

    【讨论】:

    • 是的,我需要拥有经过身份验证的用户,并且目前正在使用从信号器连接和自定义提供程序传入的身份验证令牌和 IUserProvider 一起接受身份验证令牌。
    • 另外,我确实需要将此扩展到其他功能,例如确定谁在线、朋友之间的交流等。由于我使用身份验证令牌,我对如何准确确定谁在线感到困惑.如果有人在没有注销的情况下关闭浏览器,似乎会出现断开连接。
    • 您是否查看过向 Signalr 应用程序添加身份验证的教程? asp.net/signalr/overview/security/hub-authorization
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    • 1970-01-01
    • 2016-09-19
    • 2017-12-28
    • 2015-04-27
    相关资源
    最近更新 更多