package xdi2.client.impl.websocket.endpoint; import java.net.URI; import java.util.Arrays; import java.util.List; import javax.websocket.ClientEndpointConfig; import javax.websocket.CloseReason; import javax.websocket.ContainerProvider; import javax.websocket.Decoder; import javax.websocket.Encoder; import javax.websocket.EndpointConfig; import javax.websocket.Extension; import javax.websocket.Session; import javax.websocket.WebSocketContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import xdi2.client.impl.websocket.XDIWebSocketClient; public class WebSocketClientEndpoint extends javax.websocket.Endpoint { private static final Logger log = LoggerFactory.getLogger(WebSocketClientEndpoint.class); private Session session; public static WebSocketClientEndpoint connect(XDIWebSocketClient xdiWebSocketClient, URI xdiWebSocketEndpointUri) throws Exception { // create client container WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer(); // set default timeout long oldDefaultMaxSessionIdleTimeout = webSocketContainer.getDefaultMaxSessionIdleTimeout(); long newDefaultMaxSessionIdleTimeout = 0; webSocketContainer.setDefaultMaxSessionIdleTimeout(newDefaultMaxSessionIdleTimeout); if (log.isDebugEnabled()) log.debug("Changed default max session idle timeout from " + oldDefaultMaxSessionIdleTimeout + " to " + newDefaultMaxSessionIdleTimeout); // connect return connect(webSocketContainer, xdiWebSocketClient, xdiWebSocketEndpointUri); } private static WebSocketClientEndpoint connect(WebSocketContainer webSocketContainer, XDIWebSocketClient xdiWebSocketClient, URI xdiWebSocketEndpointUri) throws Exception { // init websocket endpoint List<String> preferredSubprotocols = Arrays.asList(new String[] { "xdi" }); List<Extension> extensions = null; List<Class<? extends Encoder>> encoders = null; List<Class<? extends Decoder>> decoders = null; ClientEndpointConfig.Configurator clientEndpointConfigConfigurator = new ClientEndpointConfig.Configurator() { }; ClientEndpointConfig.Builder clientEndpointConfigBuilder = ClientEndpointConfig.Builder.create(); clientEndpointConfigBuilder.preferredSubprotocols(preferredSubprotocols); clientEndpointConfigBuilder.extensions(extensions); clientEndpointConfigBuilder.encoders(encoders); clientEndpointConfigBuilder.decoders(decoders); clientEndpointConfigBuilder.configurator(clientEndpointConfigConfigurator); ClientEndpointConfig clientEndpointConfig = clientEndpointConfigBuilder.build(); clientEndpointConfig.getUserProperties().put("xdiWebSocketClient", xdiWebSocketClient); clientEndpointConfig.getUserProperties().put("xdiWebSocketEndpointUri", xdiWebSocketEndpointUri); // connect websocket endpoint WebSocketClientEndpoint webSocketEndpoint = new WebSocketClientEndpoint(); Session session = webSocketContainer.connectToServer(webSocketEndpoint, clientEndpointConfig, URI.create(xdiWebSocketEndpointUri.toString())); webSocketEndpoint.setSession(session); // done log.info("Connected WebSocket endpoint for " + xdiWebSocketEndpointUri + " with preferred subprotocols " + preferredSubprotocols); return webSocketEndpoint; } @Override public void onOpen(Session session, EndpointConfig endpointConfig) { // set timeout long oldMaxIdleTimeout = session.getMaxIdleTimeout(); long newMaxIdleTimeout = 0; session.setMaxIdleTimeout(newMaxIdleTimeout); if (log.isDebugEnabled()) log.debug("Changed max idle timeout of session " + session.getId() + " from " + oldMaxIdleTimeout + " to " + newMaxIdleTimeout); // read properties ClientEndpointConfig clientEndpointConfig = (ClientEndpointConfig) endpointConfig; URI xdiWebSocketEndpointUri = (URI) clientEndpointConfig.getUserProperties().get("xdiWebSocketEndpointUri"); // init message handler WebSocketClientMessageHandler webSocketMessageHandler = new WebSocketClientMessageHandler(session); // init session log.info("WebSocket session " + session.getId() + " opened (" + xdiWebSocketEndpointUri + ")."); session.addMessageHandler(webSocketMessageHandler); session.getUserProperties().putAll(clientEndpointConfig.getUserProperties()); } @Override public void onClose(Session session, CloseReason closeReason) { log.info("WebSocket session " + session.getId() + " closed."); XDIWebSocketClient xdiWebSocketClient = (XDIWebSocketClient) session.getUserProperties().get("xdiWebSocketClient"); xdiWebSocketClient.close(); } @Override public void onError(Session session, Throwable throwable) { log.error("WebSocket session " + (session != null ? session.getId() : session) + " problem: " + throwable.getMessage(), throwable); if (session != null) { XDIWebSocketClient xdiWebSocketClient = (XDIWebSocketClient) session.getUserProperties().get("xdiWebSocketClient"); xdiWebSocketClient.close(); } } /* * Getters and setters */ public Session getSession() { return this.session; } public void setSession(Session session) { this.session = session; } }