websocket自动closures连接

我在build立一个基于jetty的embedded式websocket服务器的应用程序。 客户端是谷歌浏览器中默认的websocket实现。 一切正常,只有在连接closures一段时间后,服务器和客户端之间没有传输。 我不确定谁closures了连接:docker服务器或chrome浏览器。

我想这个解决scheme是每隔x秒发送一条消息,但我打开更好的解决scheme。

所以…我的问题是:

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

  2. 这是什么更多的docker相关,并有多less与websocket协议? 在这种情况下,如何在docker禁用这个function?

  3. 还有其他问题吗?

谢谢

更新:即使我发送1消息/秒仍连接closures

在回答你的第三个问题时,你的客户希望能够应对临时的networking问题,比如让用户在hibernate的会议之间closures笔记本电脑,或者networking暂时closures。

解决方法是在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); }; } 

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

我发现了另一个相当快速和肮脏的解决scheme。 如果使用低级方法来实现WebSocket,并且您自己实现onOpen方法,则会收到实现WebSocket.Connection接口的对象。 这个对象有一个你可以调整的setMaxIdleTime方法。

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

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

刚刚为自己find了解决办法。 你想要设置的是WebSocketServlet的maxIdleTime,以毫秒为单位。 如何做到这一点取决于你如何configuration你的servlet。 用Guice ServletModule,你可以做10小时超时这样的事情:

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

任何一个<0都是无限的空闲时间,我相信。

我相信这是一个docker问题。 我还没有看到任何浏览器由于不活动而closuresWebSocket连接,也没有遇到其他WebSocket连接超时的WebSocket服务器。

Jetty主要专注于构build基于HTTP的应用程序servlet。 在这种情况下,HTTP连接需要非常积极地进行清理,并且HTTP不是为长期连接而devise的,所以短暂的默认超时是合理的。

我还没有看到你所描述的确切问题(即使是在活动中也要closures),但是在30秒的不活动状态之后,我确实看到了WebSocket连接closures了。 由于某些其他原因,在较旧版本的Jetty或当前版本中,定时器可能不会被WebSocket活动重置。 我通过使用BlockingChannelConnector对象上的setMaxIdleTime方法来解决此问题,以将超时值设置为整数MAX_VALUE。

我认为你正在经历的这个超时实际上是TCP / IP的一部分,解决办法是在短时间内发送空的消息。

下面是一个关于如何使用WebSocketServletconfigurationJetty的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,但会话不pipe。 对我来说,它看起来是客户端(浏览器)超时,然后挂断。

不知道如何解决它。