Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connection timeout using standard JSR356 WebSocket client

I have a Java application that connects to a remote websocket server. As a client, I'm using the standard Java EE JSR356 WebSocket API:

javax.websocket.WebSocketContainer.connectToServer(...)

However, I haven't found a way to specify a connection timeout using this API. When I call the connectToServer(...) method, it block until it establishes a connection (which may never happen).

Is there a way to specify a connection timeout using the standard API? If not, are there any workarounds?

like image 512
Tihomir Meščić Avatar asked Oct 31 '22 09:10

Tihomir Meščić


2 Answers

Unfortunately, this is not exposed by JSR 356 - WebSocket API for Java. You will need to use implementation feature, such as HANDSHAKE_TIMEOUT in Tyrus (reference implementation). Other implementations will most likely have something similar.

Seems like there is no ticket about this yet in WEBSOCKET_SPEC, so you can add one if you want (I was able to find only issue which is mentioning SSL properties - WEBSOCKET_SPEC-210).

like image 52
Pavel Bucek Avatar answered Nov 16 '22 09:11

Pavel Bucek


You can simply override the method connectToServer in WsWebSocketContainer

public class WsWebSocketContainer2 extends WsWebSocketContainer {

    @Override
    public Session connectToServer(Object pojo, URI path) throws DeploymentException {
        ClientEndpoint annotation = pojo.getClass().getAnnotation(ClientEndpoint.class);
        if (annotation == null) {
            throw new DeploymentException("wsWebSocketContainer.missingAnnotation");
        }

        Endpoint ep = new PojoEndpointClient(pojo, Arrays.asList(annotation.decoders()));

        Class<? extends ClientEndpointConfig.Configurator> configuratorClazz = annotation.configurator();

        ClientEndpointConfig.Configurator configurator = null;
        if (!ClientEndpointConfig.Configurator.class.equals(configuratorClazz)) {
            try {
                configurator = configuratorClazz.getConstructor().newInstance();
            } catch (ReflectiveOperationException e) {
                throw new DeploymentException("wsWebSocketContainer.defaultConfiguratorFail", e);
            }
        }

        ClientEndpointConfig.Builder builder = ClientEndpointConfig.Builder.create();
        // Avoid NPE when using RI API JAR - see BZ 56343
        if (configurator != null) {
            builder.configurator(configurator);
        }
        ClientEndpointConfig config = builder.decoders(Arrays.asList(annotation.decoders())).encoders(Arrays.asList(annotation.encoders()))
                .preferredSubprotocols(Arrays.asList(annotation.subprotocols())).build();
        Map<String, Object> userProperties = config.getUserProperties();
        userProperties.put(Constants.IO_TIMEOUT_MS_PROPERTY, 999999);
        return connectToServer(ep, config, path);
    }
}
like image 21
BenMansourNizar Avatar answered Nov 16 '22 09:11

BenMansourNizar