在我的应用程序中,我在Web服务器上托管一个相当CPU密集型的引擎,该服务器通过SignalR连接到客户端。从客户端,服务器将被发信号通知(通过AJAX请求),每200ms将发送一个“动画事件”队列,描述正在进行的工作。
这是用于在客户端上设置连接的代码:
$.connection.hub.start({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] })
这是后端的相关代码:
private const int PUSH_INTERVAL = 200;
private ManualResetEvent _mrs;
private void SetupTimer(bool running)
{
if (running)
{
UpdateTimer = new Timer(PushEventQueue, null, 0, PUSH_INTERVAL);
}
else
{
/* Lock here to prevent race condition where the final call to PushEventQueue()
* could be followed by the timer calling PushEventQueue() one last time and
* thus the End event would not be the final event to arrive clientside,
* which causes a crash */
_mrs = new ManualResetEvent(false);
UpdateTimer.Dispose(_mrs);
_mrs.WaitOne();
Observer.End();
PushEventQueue(null);
}
}
private void PushEventQueue(object state)
{
SentMessages++;
SignalRConnectionManager<SimulationHub>.PushEventQueueToClient(ConnectionId, new AnimationEventSeries { AnimationPackets = SimulationObserver.EventQueue.FlushQueue(), UpdateTime = DateTime.UtcNow });
}
public static void PushEventQueueToClient(string connectionId, AnimationEventSeries series)
{
HubContext.Clients.Client(connectionId).queue(series);
}
为了完整起见,相关的Javascript方法:
self.hub.client.queue = function(data) {
self.eventQueue.addEvents(data);
};
在localhost上测试此功能时,它使用serverSentEvents作为传输方法,绝对顺利,没有延迟(如您所料)。
但是,在生产中使用时,通常需要很长时间才能完成。使用SignalR的日志记录和我自己的一些仪器,可以看出第一系列事件在几秒钟内到达客户端,这是完全可以接受的。但是,在此之后,SignalR经常会出现以下错误:
Keep alive has been missed, connection may be dead/slow.
很快跟进:
Keep alive timed out. Notifying transport that connection has been lost.
这将发生几次,然后最终,在一分钟之后,事件将到达,我自己的仪器显示他们从服务器发出约200ms的间隔,如预期的那样。还可以看出,在生产中,它们是通过主要传输方法,网络套接字发送的。
是否有人知道在计时器上发送多个SignalR请求可能导致的任何问题?就像我说的,这似乎主要发生在Web套接字上。我被告知使用网络套接字是最好的做法,所以我很想继续使用它们,但如果没有针对这些问题的解决方法,那么我担心我必须永久删除它们
我现在已经删除了在实际站点上使用Web套接字的选项,并且我遇到了与服务器发送事件相同的问题 - 在第一次队列更新到达后,有几次尝试重新连接失败。
答案 0 :(得分:6)
总结我们的讨论,我认为天蓝色的websockets / signalr没有具体问题。
我在这里提供示例代码:https://github.com/jonegerton/SignalR.StockTicker可用于测试,并进行一些小调整(我可能会在某些时候将其作为测试平台开发)。
它基于MS的示例项目,可在此处找到:https://github.com/SignalR/SignalR-StockTicker。
我在这里放了一个例子(http://stockticker.azurewebsites.net)用于测试目的。它启用了默认传输配置(即websockets&gt;&gt; serversentevents&gt;&gt; longpolling)