【问题标题】:SignalR client specific with angularjsSignalR 客户端特定于 angularjs
【发布时间】:2016-05-27 01:09:45
【问题描述】:

所以我对 signalR 还很陌生,并且曾在 MVC 上使用过它。现在我在带有 angularjs 的 webapi 中使用它,有点困惑或者忘记了我做了什么。我正在使用带有 webapi 的不记名令牌,并正在尝试创建一个通知系统。

我想弄清楚的是使用 angularjs 和 signalR 的正确方法。我看到很多人在/调用时使用代理。当我从服务器调用 hubcontext 时,proxy.on 是这样的吗:

IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>(); hubContext.Clients.User(UserId).broadcastNotification("Good morning! The time is " + DateTime.Now.ToString());

proxy.invoke 方法来自客户端?如果是这样,哪一种是使用通知系统的最佳方式(我会假设 proxy.on)?

我的第二个问题更多关于向特定用户发送通知。对于向特定用户发送请求,我假设您希望在集线器上这样做:

public void SendNotification(string userId) { Clients.User(userId).broadcastNotification("Good morning! The time is " + DateTime.Now.ToString()); }

我的创业公司是这样的:

 public class MyProvider : IUserIdProvider
    {
        public string GetUserId(IRequest request)
        {
            var userId = request.User.Identity.Name;
            return userId.ToString();
        }
    }
    public void Configuration(IAppBuilder app)
    { 
        HttpConfiguration config = new HttpConfiguration();
        ConfigureOAuth(app);
        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<AuthContext, Travelfy.API.Migrations.Configuration>());
        GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => new MyProvider());
        app.MapSignalR("/hubs", new HubConfiguration());

    }

当我刷新页面时,我注意到我所有的用户 ID 都是空字符串“”。我读到这可能是由于使用了不记名令牌。如果是这样,我将如何使用不记名令牌来指定我想要发送到的用户 ID?当我使用 Clients.All 一切正常,所以我假设它必须与我得到的启动/用户 ID 相关。

谢谢

【问题讨论】:

    标签: asp.net angularjs asp.net-web-api signalr signalr-hub


    【解决方案1】:

    回答你的第一个问题:

    这将是使用通知系统的最佳方式

    如果你想从服务器向客户端推送通知,你必须定义一个新的处理程序是在客户端(使用生成的代理)上定义一个方法,如下所示:

    How to define methods on the client that the server can call

    如果您希望客户端调用位于服务器上的方法,则必须使用此方法:

    How to call server methods from the client

    回答你的第二个问题:

    对于向特定用户发送请求,我假设您希望 在集线器上执行此操作

    您可以使用您希望定位的客户端的connection ID。看到这个:

    Calling client methods

    【讨论】:

    • 谢谢。当我有机会时,我会看看这个。很可能会有更多问题。
    • 我相信我的问题是关于 Irequest 值 MyProvider 对于 userName 和 authenticationType 为空。我相信这是因为我使用的是不记名令牌而不是 Cookie。我将如何通过 Irequest 的 userId/userName?
    • 我不确定你的问题是什么。您想知道如何使用连接 ID 从服务器端调用客户端吗?您可以在服务器端的 SignalR 集线器中使用 OnConnected() 方法,并将连接的客户端的连接 ID 添加到使用其主机名作为键的字典中。然后,您可以在其他地方实例化集线器并使用字典中的连接 ID 定位特定客户端。希望这会有所帮助。
    • 很抱歉给您带来了困惑。我的问题是从集线器实例或集线器类调用您的方法是否更合理?此外,如果我使用的是集线器实例,我将如何获取 connectionIds 并向正确的 connectionId 发送通知?当我只是将 context.connectionid 放在集线器类中时,我将其发送给我自己,而不是我想发送给的人。在那种情况下,我需要把它放在一个表中并保存这些connectionIds吗?在这种情况下,我尝试使用 IUserProvider 返回我的用户信息,但我的结果始终为空。
    • 您可以使用类似于单例的静态类并包含将使用OnConnected() 方法添加的connectionId 字典。然后在您的控制器类中,您通过执行以下操作获取 hubContext:var hub = GlobalHost.ConnectionManager.GetHubContext&lt;HubName&gt;(); 然后您可以从字典中获取 connectionId 并像这样调用特定客户端:hub.Clients.Client(connectionId).BroadcastMethod(broadcastMessage);
    【解决方案2】:

    所以过了一会儿,我能够找出正确的答案。因为我使用的是bearerTokens,所以我真的必须确定另一种获取userId的方法,而不是仅仅依赖request.User.Identity.Name。我需要做的是将我的 bearerToken 传递给 connection.qs 值。

    connection.qs = { Bearer: token };

    一旦我能够做到这一点,我必须根据我发送的令牌路由查找我的用户。

    var token = request.QueryString.Get("Bearer"); var authenticationTicket = Startup.OAuthBearerOptions.AccessTokenFormat.Unprotect(token);

    【讨论】:

      猜你喜欢
      • 2011-12-13
      • 2014-02-15
      • 2013-03-23
      • 2016-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多