SignalR:建立连接时是否可以强制连接在服务器端使用特定传输?

Anc*_*tax 3 c# asp.net asp.net-mvc long-polling signalr

在使用SignalR开发服务器客户端推送机制时,我遇到了最大的并发连接问题.即每个浏览器进程仅支持大约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();                
    }
Run Code Online (Sandbox Code Playgroud)

Jes*_*aya 8

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

服务器代码:

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

客户代码:

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();
Run Code Online (Sandbox Code Playgroud)

我测试了这个解决方案.它在SignalR v2.2下工作.是我的Github示例项目.(不知何故,在SignalR v0.5.2下,hubConnection一旦停止就不会重启).