websocket closing connection automatically

JavaJavascriptGoogle ChromeJettyWebsocket

Java Problem Overview


I'm building an application in java that has an embedded websocket server based on jetty. The client is the default websocket implementation in google chrome. Everything is working ok, only if there is no transfer between server and client after a certain time the connection is closed. I'm not sure who's closing the connection: the jetty server or the chrome browser.

The solution to this I think is to send a message every x seconds, but I'm opened to better solutions.

SO... my questions are:

  1. Is this something that the websocket protocol requires and in this case the chrome browser is closing my connection?

  2. Is this something that is more jetty related and has more or less to do with the websocket protocol? In this case how do I disable this in jetty?

  3. Is there another problem??

Thanks

UPDATE: even if I send 1 message/second still the connection is closed

Java Solutions


Solution 1 - Java

In answer to your third question: your client wants to be able to cope with temporary network problems anyway, e.g. let's say the user closes their laptop between meetings which hibernates it, or the network simply goes down temporarily.

The solution is to listen to onclose events on the web socket client and when they occur, set a client side timeout to re-open the connection, say in a second:

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);
    };
}

Solution 2 - Java

You need to send ping messages from time to time. I think the default timeout is 300 seconds. https://stackoverflow.com/questions/10585355/sending-websocket-ping-pong-frame-from-browser

Solution 3 - Java

I found another, rather quick and dirty, solution. If you use the low level approach to implement the WebSocket and you Implement the onOpen method yourself you receive an object implementing the WebSocket.Connection interface. This object has a setMaxIdleTime method which you can adjust.

Solution 4 - Java

You can actually set the timeout interval at the Jetty server side configuration using the WebSocketServletFactory instance. For example:

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

Solution 5 - Java

I think this timeout you are experiencing is actually part of TCP/IP and the solution is to just send empty messages once in a while.

Solution 6 - Java

Just found the solution to this for myself. What you want to set is the maxIdleTime of WebSocketServlet, in millis. How to do that depends on how you config your servlet. With Guice ServletModule you can do something like this for timeout of 10 hours:

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

Anything <0 is infinite idle time I believe.

Solution 7 - Java

I believe this is a Jetty issue. I have not seen any browsers close WebSocket connections due to inactivity nor have I encountered other WebSocket servers that timeout WebSocket connections.

Jetty is (was) primarily focused on building HTTP based application servlets. In that context, HTTP connections need to be cleaned up pretty aggressively and HTTP was not designed for long-lived connections so having a short default timeout is reasonable.

I've not seen the precise problem you described (closing even with activity) but I do see WebSocket connections closed after 30 second of inactivity. It's possible that in older versions of Jetty or in the current version for some other reason, the timer is not reset by WebSocket activity. I get around this by using the setMaxIdleTime method on my BlockingChannelConnector object to set the timeout value to Integer MAX_VALUE.

Solution 8 - Java

Here is an example on how to configure Jetty's websocket timeout (the most likely culprit) using WebSocketServlet (in scala, sorry, but the syntax is pretty much the same).

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])
  }
}

Solution 9 - Java

I have a similar experience and I believe that it might be the browser that is cutting the session short. I also set the maxIdleTimeout, but the session is dropped regardless. To me, it looks like it is the client (the browser) that is timing out the session and then hangs up.

Don't know how to work around it.

Solution 10 - Java

Since @Doua Beri is experiencing connection close even when there are 1 Hz SENDs, it may be instead be due to size limits on messages.

This passage from Spring's WebSockets may be useful, with my emphasis ...

> Although in theory a WebSocket message can be almost unlimited in > size, in practice WebSocket servers impose limits — for example, 8K > on Tomcat and 64K on Jetty. For this reason STOMP clients such as > stomp.js split larger STOMP messages at 16K boundaries and send them > as multiple WebSocket messages thus requiring the server to buffer and > re-assemble.

Solution 11 - Java

Same issue: Was using WebSockets & sockjs-client/1.0.3/sockjs library with @ServerEndPoint on Java Server side. The websocket connections kept breaking variably.

I moved to using Stomp and sockJS (abandoning the @ServerEndpoint) but encountered another issue popular on SO - /info=34424 - with 404 error -

I had to abandon using the xml approach of Stomp Spring library as suggested at other places. I have Spring 4.2 in my project and many SockJS Stomp implementations usually work well with Spring Boot implementations. This implementation from Baeldung worked(for me without changing from Spring 4.2 to 5).

After Using the dependencies mentioned in his blog, it still gave me ClassNotFoundError. I added the below dependency to fix it.

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

Solution 12 - Java

This worked for me while the other solutions were not!

  1. Update your jupyters
  2. Start your jupyters via your preferred notebook or lab but add this code at the end of the line in the console: <--no-browser>

This is stopping to need to be connected to your EC2 instance all the time. Therefore even if you loose connection due to internet connection loss, whenever you gain a new wifi access it automatically re-connects to the actively working kernel.

Also, don't forget to start your jupyter in a tmux account or a ngnix or other environments like that.

Hope this helps!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDoua BeriView Question on Stackoverflow
Solution 1 - JavaAnt KutscheraView Answer on Stackoverflow
Solution 2 - JavaTarek ZeineddineView Answer on Stackoverflow
Solution 3 - JavaLeoRView Answer on Stackoverflow
Solution 4 - Javauser3499459View Answer on Stackoverflow
Solution 5 - JavaDavid GraysonView Answer on Stackoverflow
Solution 6 - JavaAkaZnView Answer on Stackoverflow
Solution 7 - JavakanakaView Answer on Stackoverflow
Solution 8 - Javauser1338062View Answer on Stackoverflow
Solution 9 - JavaAndersWView Answer on Stackoverflow
Solution 10 - JavaKen LinView Answer on Stackoverflow
Solution 11 - JavaveritasView Answer on Stackoverflow
Solution 12 - JavaSelin TosunView Answer on Stackoverflow