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:
Is this something that the websocket protocol requires and in this case the chrome browser is closing my connection?
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?
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
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!
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.
Source: Stackoverflow.com