自动关闭连接

我正在构建一个 Java 应用程序,它有一个基于 jetty 的嵌入式 websocket 服务器。客户端是默认的网络插座实现在谷歌铬。一切正常,只有在连接关闭一定时间后服务器和客户端之间没有传输的情况下。 我不确定是谁关闭了连接: 是 Jetty 服务器还是 chrome 浏览器。

我认为解决这个问题的方法是每隔 x 秒发送一条消息,但我接受更好的解决方案。

所以... 我的问题是:

  1. 这是否是 websocket 协议所要求的,在这种情况下,chrome 浏览器正在关闭我的连接?

  2. 这是不是更多地与 Jetty 相关,或多或少地与 websocket 协议有关?在这种情况下,我如何禁用这在码头?

  3. 还有别的问题吗?

谢谢

更新: 即使我每秒发送1条消息,连接仍然是关闭的

169930 次浏览

我认为您正在经历的超时实际上是 TCP/IP 的一部分,解决方案是偶尔发送空消息。

我相信这是码头的问题。我没有看到任何浏览器因为不活动而关闭 WebSocket 连接,也没有遇到其他使 WebSocket 连接超时的 WebSocket 服务器。

Jetty 主要专注于构建基于 HTTP 的应用程序 servlet。在这种情况下,需要非常积极地清理 HTTP 连接,而且 HTTP 不是为长期连接设计的,因此有一个短的默认超时是合理的。

我没有看到您所描述的确切问题(甚至关闭活动) ,但我确实看到在30秒的不活动后关闭 WebSocket 连接。由于其他原因,在旧版本的 Jetty 或当前版本中,定时器可能不会被 WebSocket 活动重置。我通过在 BlockingChannelConnector 对象上使用 setMaxIdleTime 方法将超时值设置为 Integer MAX _ VALUE 来解决这个问题。

我自己找到了解决办法。您想要设置的是 WebSocketServlet 的 maxIdleTime,单位是 milis。如何做取决于如何配置 servlet。使用 Guice ServletModule,你可以在10小时内完成以下工作:

serve("ws").with(MyWSServlet.class,
new HashMap<String, Sring>()\{\{ put("maxIdleTime", TimeUnit.HOURS.toMillis(10) + ""); }});

我相信任何 < 0的事物都是无限的空闲时间。

我找到了另一个相当快捷而肮脏的解决办法。 如果您使用底层方法来实现 WebSocket,并且您自己实现了 onOpen方法,那么您将收到一个实现 WebSocket.Connection接口的对象。这个对象有一个 SetMaxIdleTime方法,您可以调整它。

您需要不时地发送 ping 消息。我认为默认的超时时间是300秒。 从浏览器发送 websocket 乒乓框架

您实际上可以使用 WebSocketServletFactory实例在 Jetty 服务器端配置上设置超时间隔:

WebSocketHandler wsHandler = new WebSocketHandler() {
@Override
public void configure(WebSocketServletFactory factory) {
factory.getPolicy().setIdleTimeout(1500);
factory.register(MyWebSocketAdapter.class);
...
}
}

下面是一个关于如何使用 WebSocketServlet 配置 Jetty 的 websocket 超时(最有可能的元凶)的示例(在 scala 中,抱歉,但语法几乎是相同的)。

import javax.servlet.annotation.WebServlet
import org.eclipse.jetty.websocket.servlet.{WebSocketServletFactory, WebSocketServlet}


@WebServlet(name = "WebSocket Servlet")
class WebsocketServlet extends WebSocketServlet {
override def configure(factory: WebSocketServletFactory): Unit = {
factory.getPolicy.setIdleTimeout(1000 * 3600)
factory.register(classOf[ClientWebsocket])
}
}

我有类似的经历,我相信可能是浏览器缩短了会话。我还设置了 maxIdleTimeout,但无论如何都会删除会话。对我来说,它看起来像是客户端(浏览器)正在计时会话,然后挂断。

不知道该怎么办。

回答你的第三个问题: 无论如何,你的客户希望能够处理暂时的网络问题,例如,假设用户在休眠的会议之间关闭他们的笔记本电脑,或者网络只是暂时关闭。

解决方案是监听 Web 套接字客户端上的 onclose事件,当它们发生时,设置一个客户端超时以重新打开连接,比如说:

function setupWebSocket(){
this.ws = new WebSocket('wss://host:port/path');
this.ws.onerror = ...;
this.ws.onopen = ...;
this.ws.onmessage = ...;
this.ws.onclose = function(){
setTimeout(setupWebSocket, 1000);
};
}

同样的问题: 在 Java 服务器端使用 WebSockets & sockjs-client/1.0.3/sockjs 库和@ServerEndPoint。

我转而使用 Stomp 和 sockJS (放弃@ServerEndpoint) ,但是遇到了另一个在 SO-/info = 34424上很流行的问题——404错误-

我不得不放弃使用 StompSpring 库的 xml 方法,就像在 其他中建议的那样。我的项目中有 Spring 4.2,许多 SockJS Stomp 实现通常与 Spring Boot 实现一起工作得很好。来自 Baeldung 的实施工作(对我来说,没有从 Spring 4.2改为5)。

在使用了他的博客中提到的依赖项之后,它仍然给了我 ClassNotFoundError。我添加了下面的依赖项来修复它。

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>

这对我有效,而其他的解决方案却没有效果!

  1. 更新你的木星
  2. 通过您首选的笔记本或实验室启动 Jupyters,但是在控制台的行尾添加以下代码: < ——无浏览器 >

这是停止需要连接到您的 EC2实例所有的时间。因此,即使你由于网络连接中断而失去连接,每当你获得一个新的 wifi 访问权限时,它会自动重新连接到正在运行的内核。

另外,不要忘记在 tmux 帐户或 nnix 或其他类似的环境中启动 Jupyter。

希望这个能帮上忙!

由于@Doua Beri 正在经历连接关闭,即使有1赫兹的发送,这可能是由于 尺寸限制的消息。

这段来自 Spring 的 WebSockets的文章可能是有用的,我的重点是..。

尽管理论上 WebSocket 消息在 在实际应用中,WebSocket 服务器规定了一些限制ーー例如,< strong > < em > 8K 在 Tomcat 和 Jetty 上使用64K Js 将较大的 STOMP 消息在16K 的边界上拆分并发送 作为多个 WebSocket 消息,因此需要服务器进行缓冲和 重新组装。