我将首先从我所知道的开始,因为它可能对其余部分有用。
很明显,您可以使用协议的子集实例化SockJS:
sockJsProtocols = ["xhr-streaming", "xhr-polling", ....];
socket.cliente = new SockJS(url, null, {transports: sockJsProtocols}));
[我还发现,当SockJS调用/ info端点时,服务器返回的websocket为true或false(取决于服务器的兼容性)。
[我也知道有3列的漂亮表here:websockets,流和轮询。
但是我有两个问题:
1)SockJS如何决定轮询,流式传输或Web套接字?它不能与浏览器兼容,因为我在日志中看到了许多与最近的浏览器的XHRStreaming会话。如何在任何地方都没有记录?
2)为什么SockJS每次都需要调用/ info?服务器的兼容性将始终相同。
确定,我必须阅读SockJS客户端的源代码才能了解其工作原理。现在我知道了。该答案至少在SockJS 1.3上有效。
SockJS正在计算/ info调用的RTT(往返时间)。然后,将花费此时间并计算RTO(重传超时)。如果RTT小于100毫秒,则只需将其增加300毫秒,否则将其乘以4。
然后将RTO乘以每个协议的往返次数,显然对于websocket等于2。
然后将其用作超时,从我们打开websocket连接开始,直到收到OPENED帧(Stomp CONNECTED帧)。当超时时,SockJS只是关闭协议套接字并尝试下一个。如果没有可用的协议,它将再次重试。
根据团队进行的一些实验,整个逻辑听起来非常具有数据性和推测性。为什么是300ms?为什么websocket的往返次数是2?而且更令人惊讶的是,无论是在客户端还是在服务器端都不能真正覆盖此值(服务器可以使用/ info调用中的响应覆盖此值)
这实际上意味着,如果您的Stomp服务器创建队列的速度太慢,客户端将在协商中丢失。
假设您的客户端与服务器相距不远,那么它很可能会回退到<100毫秒的RTT中。因此,客户端必须在700-800毫秒之间接收CONNECTED帧。
我找不到解决此问题的另一种方法,除了使用过滤器将/ info调用的处理速度减慢一定量后,该量是根据测量到我们的经纪人中继的平均滞后时间凭经验计算得出的。