【问题标题】:SignalR: Is it possible to force a connection to use a specific transport on the server side as the connection is established?SignalR:是否可以在连接建立时强制连接使用服务器端的特定传输?
【发布时间】:2015-02-17 08:36:36
【问题描述】:

在使用 SignalR 开发服务器客户端推送机制时,我遇到了最大并发连接问题。 IE。每个浏览器进程仅支持到同一域的大约 6 个并发连接。

我目前正在跟踪哪些用户与哪些连接相关联,并且在用户打开三个连接后,我想强制来自同一用户的其他连接使用长轮询进行传输,而不是 Web 套接字。通过这种方式,我希望完全避免连接用完的问题。

我总是可以在客户端上执行此操作,服务器提供非 SignalR 机制来通知客户端是否已用完 Web 套接字连接,然后客户端可以在打开 SignalR 连接时指定长轮询,但这似乎效率低下.我真的很想在连接打开时适当地设置传输。

集线器类中类似于以下内容。

    /// <summary>
    /// Chooses the correct transport depending on a users connections
    /// </summary>        
    public override Task OnConnected()
    {
        if(CanOpenWebSocketsConnection(Context.User.Identity.Name))
        {
            Connection.Transport = Connections.WebSockets;
        }
        else
        {
            Connection.Transport = Connections.LongPolling;
        }
        return base.OnConnected();                
    }

【问题讨论】:

  • 为什么不强制每个客户端只有一个连接?从长远来看,您的服务器将更具可扩展性。
  • 定义客户端,客户端是IP地址,还是用户?如果我们采用这种方法,那么我们将无法利用 webclient 传输通过 SignalR 提供动态更新,而不会阻止用户打开另一个选项卡到站点上的任何页面。使用上述方法,我们将两全其美。动态更新,回退到频率稍低的更新,用户可以打开任意数量的选项卡。值得一提的是,这不必超过几百个用户。
  • 您自己承认您允许每个用户有多个连接。我很抱歉在我原来的评论中使用了客户这个词。与同一用户建立多个连接是在浪费服务器资源。所有通信都可以通过同一条线路进行。
  • 它可以,请参阅Channel Messaging 和这个response。不过,我们对所描述的方法非常满意。

标签: c# asp.net asp.net-mvc signalr long-polling


【解决方案1】:

作为传统的 longPolling 和 iFrame 机制,SignalR 传输类型是由客户端而不是服务器发起的。 SignalR 只是这些传输类型的包装器。此问题的解决方法是让服务器告诉客户端使用特定类型重新连接。

服务器代码:

[HubName("moveShape")]
public class MoveShapeHub : Hub
{
    public override Task OnConnected()
    {
        if (Context.QueryString["transport"] == "webSockets")
        {
            return Clients.Caller.changeTransport("longPolling");
        }
    }
}

客户端代码:

var hubConnection = new HubConnection("http://localhost:1235/");
var hub = hubConnection.CreateHubProxy("moveShape");

hub.On<string>("changeTransport", transportName =>
    Dispatcher.InvokeAsync(() =>
    {
        if (transportName == "longPolling")
        {
            hubConnection.Stop();
            hubConnection.Start(new LongPollingTransport());
        }
    }));

await hubConnection.Start();

我已经测试过这个解决方案。它在 SignalR v2.2 下工作。 Here 是我的 Github 示例项目。 (不知为何,在 SignalR v0.5.2 下,hubConnection 停止后不会重新启动)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    相关资源
    最近更新 更多