Sockjs/socketio 断开连接延迟在 apache 代理后面



我需要处理用户与在 xhr-polling 模式下运行的sockjs 应用程序断开连接的问题。当我连接到本地主机时,一切都按预期工作。当我在 nodejs 和浏览器之间放置 apache 时,我在关闭浏览器和 nodejs 内部断开连接事件之间得到 ~20 秒的延迟。我的 apache 代理配置如下:

<Location />
ProxyPass http://127.0.0.1:8080/
ProxyPassReverse http://127.0.0.1:8080/
</Location>

文件的其余部分是默认的,您可以在此处看到它。我尝试使用 ttl=2 和超时 = 2 选项,但要么没有任何变化,要么我每 2 秒重新连接一次而不关闭浏览器。如何减少额外的断开连接超时,但 apache 在其默认值中的某个地方引入?

您的 Apache 服务器可能配置为使用 HTTP Keep Aalive,这将保持持久连接打开。在这种情况下,我会尝试禁用KeepAlive,或降低 Apache 配置中的KeepAliveTimeout设置,看看这是否可以解决问题。

如果这不起作用,我还会查看netstat,看看每个套接字的状态是什么,并开始根本原因分析。此图表给出的是TCP状态机,可以告诉您每个连接的位置。Wireshark还可以为您提供一些有关正在发生的事情的信息。

在长轮询中,连接发生如下

<client> ---> apache ---> <node.js>

当客户端断开连接时

<client> -X-> apache ---> <node.js>

Apache仍然保持连接打开。现在有两种解决方法

代理超时

您可以在下面添加到您的 apache 配置中

ProxyTimeout 10

这将在 10 秒后断开连接,但随后会在 10 秒后断开每个长轮询连接,这是您不希望的

下一个选项是 ping 客户端

ping超时(数字):有多少毫秒没有pong数据包,以考虑连接已关闭(60000)

ping间隔(数字):发送新的ping数据包(25000)之前的毫秒数。

var io = require('socket.io')(server, { 'transports': ['polling'], pingTimeout: 5000, pingInterval: 2500});

上面将确保客户端在关闭后 5 秒内断开连接,您可以进一步降低它,但这可能会影响通常的加载场景

但是通读所有帖子、线程和站点,我认为您无法复制直接连接到socket.io时获得的行为,因为连接中断很容易被socket.io

检测到

20 秒延迟不在 apache 代理中。我遇到了同样的问题,延迟未在本地 URL 中发生,但延迟发生在全局 URL 中。

这个问题在 NodeJs 本身中得到了解决。需要将一次性数据从服务器发送到客户端以确保其已初始化。此问题不在 WebSocket 插件的文档和问题博客中。

在服务器中接受请求后发送虚拟消息,如下所示。

let connection = request.accept(null, request.origin);
connection.on('message', function (evt) {
console.log(evt);
});
connection.on('close', function (evt) {
console.log(evt);
});
connection.send("Success"); //dummy message to the client from server

最新更新