C# 信令员:在建立连接时,是否可以强制连接使用服务器端的特定传输?
在使用signar开发服务器-客户机推送机制时,我遇到了最大并发连接问题。即,每个浏览器进程只支持大约6个到同一域的并发连接 我目前正在跟踪哪些用户与哪些连接相关联,并且在一个用户有三个打开的连接之后,我希望强制来自同一用户的其他连接对传输使用长轮询,而不是web套接字。通过这种方式,我希望完全避免连接耗尽的问题 我总是可以在客户端上这样做,服务器提供一个非信号器机制来通知客户端是否已用完web套接字连接,然后客户端可以在打开信号器连接时指定长轮询,但这似乎效率低下。我真的希望在连接打开时将传输设置为适当 在hub类中类似于以下内容C# 信令员:在建立连接时,是否可以强制连接使用服务器端的特定传输?,c#,asp.net,asp.net-mvc,signalr,long-polling,C#,Asp.net,Asp.net Mvc,Signalr,Long Polling,在使用signar开发服务器-客户机推送机制时,我遇到了最大并发连接问题。即,每个浏览器进程只支持大约6个到同一域的并发连接 我目前正在跟踪哪些用户与哪些连接相关联,并且在一个用户有三个打开的连接之后,我希望强制来自同一用户的其他连接对传输使用长轮询,而不是web套接字。通过这种方式,我希望完全避免连接耗尽的问题 我总是可以在客户端上这样做,服务器提供一个非信号器机制来通知客户端是否已用完web套接字连接,然后客户端可以在打开信号器连接时指定长轮询,但这似乎效率低下。我真的希望在连接打开时将传输
/// <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();
}
//
///根据用户连接选择正确的传输
///
已连接的公用覆盖任务()
{
if(CanOpenWebSocketsConnection(Context.User.Identity.Name))
{
Connection.Transport=Connections.WebSockets;
}
其他的
{
Connection.Transport=Connections.LongPolling;
}
返回base.OnConnected();
}
由于传统的长轮询和iFrame机制,信号传输类型由客户端而不是服务器启动。信号器只是这些传输类型的包装器。解决此问题的一个方法是让服务器告诉客户端使用特定类型重新连接
服务器代码:
[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();
var hubConnection=新的hubConnection(“http://localhost:1235/");
var hub=hubConnection.CreateHubProxy(“moveShape”);
hub.On(“changeTransport”,transportName=>
Dispatcher.InvokeAsync(()=>
{
如果(transportName==“longPolling”)
{
hubbonnection.Stop();
hubConnection.Start(新的LongPollingTransport());
}
}));
等待连接。开始();
我已经测试过这个解决方案。它在SignalR v2.2下工作。这是我的Github示例项目。(在SignalR v0.5.2下,HUB连接在停止后不会重新启动)。为什么不强制每个客户端只有一个连接总数?从长远来看,您的服务器将更具可扩展性。定义客户端,客户端是IP地址还是用户?如果我们采用这种方法,那么我们将无法利用webclient传输通过SignalR提供动态更新,而不阻止用户打开站点上任何页面的另一个选项卡。使用上述方法,我们将两全其美。动态更新,回退到稍微不频繁的更新,用户可以打开任意多个选项卡。值得一提的是,它不必扩展到几百个用户之外。您自己承认,您允许每个用户有多个连接。很抱歉在我最初的评论中使用了client这个词。与同一用户建立多个连接是在浪费服务器资源。所有的通讯都可以通过同一条线路。它可以,看到,还有这个。然而,我们对所描述的方法非常满意。