[java] websocket closing connection automatically

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

This question is related to java javascript google-chrome jetty websocket

The answer is


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.


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>

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!


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.


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

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.


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.


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

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.


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

You need to send ping messages from time to time. I think the default timeout is 300 seconds. Sending websocket ping/pong frame from browser


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.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to google-chrome

SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81 SameSite warning Chrome 77 What's the net::ERR_HTTP2_PROTOCOL_ERROR about? session not created: This version of ChromeDriver only supports Chrome version 74 error with ChromeDriver Chrome using Selenium Jupyter Notebook not saving: '_xsrf' argument missing from post How to fix 'Unchecked runtime.lastError: The message port closed before a response was received' chrome issue? Selenium: WebDriverException:Chrome failed to start: crashed as google-chrome is no longer running so ChromeDriver is assuming that Chrome has crashed WebDriverException: unknown error: DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser How to make audio autoplay on chrome How to handle "Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first." on Desktop with Chrome 66?

Examples related to jetty

java.io.IOException: Broken pipe How to check heap usage of a running JVM from the command line? Is there a way to pass jvm args via command line to maven? Jetty: HTTP ERROR: 503/ Service Unavailable websocket closing connection automatically IOException: Too many open files

Examples related to websocket

Failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED WebSockets and Apache proxy : how to configure mod_proxy_wstunnel? javax.websocket client simple example getting the reason why websockets closed with close code 1006 Websocket onerror - how to read error description? WebRTC vs Websockets: If WebRTC can do Video, Audio, and Data, why do I need Websockets? How to make cross domain request How to use Tomcat 8 in Eclipse? Setting up a websocket on Apache? Differences between TCP sockets and web sockets, one more time