@Override public Mono<Void> execute(URI url, HttpHeaders headers, WebSocketHandler handler) { return executeInternal(url, headers, handler); }
@Override public Mono<Void> execute(URI url, HttpHeaders headers, WebSocketHandler handler) { return executeInternal(url, headers, handler); }
@Override public Mono<Void> execute(URI url, HttpHeaders headers, WebSocketHandler handler) { return executeInternal(url, headers, handler); }
private Mono<Void> executeInternal(URI url, HttpHeaders requestHeaders, WebSocketHandler handler) { MonoProcessor<Void> completionMono = MonoProcessor.create(); return Mono.fromCallable( () -> { if (logger.isDebugEnabled()) { logger.debug("Connecting to " + url); } List<String> protocols = handler.getSubProtocols(); DefaultConfigurator configurator = new DefaultConfigurator(requestHeaders); Endpoint endpoint = createEndpoint(url, handler, completionMono, configurator); ClientEndpointConfig config = createEndpointConfig(configurator, protocols); return this.webSocketContainer.connectToServer(endpoint, config, url); }) .subscribeOn(Schedulers.elastic()) // connectToServer is blocking .then(completionMono); }
@Parameters(name = "client[{0}] - server [{1}]") public static Object[][] arguments() throws IOException { WebSocketClient[] clients = new WebSocketClient[] { new TomcatWebSocketClient(), new JettyWebSocketClient(), new ReactorNettyWebSocketClient(), new UndertowWebSocketClient(Xnio.getInstance().createWorker(OptionMap.EMPTY)) }; Map<HttpServer, Class<?>> servers = new LinkedHashMap<>(); servers.put(new TomcatHttpServer(TMP_DIR.getAbsolutePath(), WsContextListener.class), TomcatConfig.class); servers.put(new JettyHttpServer(), JettyConfig.class); servers.put(new ReactorHttpServer(), ReactorNettyConfig.class); servers.put(new UndertowHttpServer(), UndertowConfig.class); Flux<WebSocketClient> f1 = Flux.fromArray(clients).concatMap(c -> Flux.just(c).repeat(servers.size())); Flux<HttpServer> f2 = Flux.fromIterable(servers.keySet()).repeat(clients.length); Flux<Class<?>> f3 = Flux.fromIterable(servers.values()).repeat(clients.length); return Flux.zip(f1, f2, f3).map(Tuple3::toArray).collectList().block() .toArray(new Object[clients.length * servers.size()][2]); }
private Mono<Void> executeInternal(URI url, HttpHeaders headers, WebSocketHandler handler) { MonoProcessor<Void> completion = MonoProcessor.create(); return Mono.fromCallable( () -> { if (logger.isDebugEnabled()) { logger.debug("Connecting to " + url); } List<String> protocols = handler.getSubProtocols(); ConnectionBuilder builder = createConnectionBuilder(url); DefaultNegotiation negotiation = new DefaultNegotiation(protocols, headers, builder); builder.setClientNegotiation(negotiation); return builder.connect().addNotifier( new IoFuture.HandlingNotifier<WebSocketChannel, Object>() { @Override public void handleDone(WebSocketChannel channel, Object attachment) { handleChannel(url, handler, completion, negotiation, channel); } @Override public void handleFailed(IOException ex, Object attachment) { completion.onError(new IllegalStateException("Failed to connect to " + url, ex)); } }, null); }) .then(completion); }
/** * Create a {@link ConnectionBuilder} for the given URI. * <p>The default implementation creates a builder with the configured * {@link #getXnioWorker() XnioWorker} and {@link #getByteBufferPool() ByteBufferPool} and * then passes it to the {@link #getConnectionBuilderConsumer() consumer} * provided at construction time. */ protected ConnectionBuilder createConnectionBuilder(URI url) { ConnectionBuilder builder = io.undertow.websockets.client.WebSocketClient .connectionBuilder(getXnioWorker(), getByteBufferPool(), url); this.builderConsumer.accept(builder); return builder; }
@Bean public ReactorNettyWebSocketClient reactorNettyWebSocketClient(HttpClient httpClient) { return new ReactorNettyWebSocketClient(httpClient); } }
private Mono<Void> executeInternal(URI url, HttpHeaders headers, WebSocketHandler handler) { MonoProcessor<Void> completionMono = MonoProcessor.create(); return Mono.fromCallable( () -> { if (logger.isDebugEnabled()) { logger.debug("Connecting to " + url); } Object jettyHandler = createHandler(url, handler, completionMono); ClientUpgradeRequest request = new ClientUpgradeRequest(); request.setSubProtocols(handler.getSubProtocols()); UpgradeListener upgradeListener = new DefaultUpgradeListener(headers); return this.jettyClient.connect(jettyHandler, url, request, upgradeListener); }) .then(completionMono); }
@Test public void sessionClosing() throws Exception { this.client.execute(getUrl("/close"), session -> { logger.debug("Starting.."); return session.receive() .doOnNext(s -> logger.debug("inbound " + s)) .then() .doFinally(signalType -> { logger.debug("Completed with: " + signalType); }); }) .block(TIMEOUT); }
@Override public Mono<Void> execute(URI url, WebSocketHandler handler) { return execute(url, new HttpHeaders(), handler); }
@Override public Mono<Void> execute(URI url, WebSocketHandler handler) { return execute(url, new HttpHeaders(), handler); }
@Override public Mono<Void> execute(URI url, WebSocketHandler handler) { return execute(url, new HttpHeaders(), handler); }
@Override public Mono<Void> execute(URI url, WebSocketHandler handler) { return execute(url, new HttpHeaders(), handler); }
private StandardWebSocketHandlerAdapter createEndpoint(URI url, WebSocketHandler handler, MonoProcessor<Void> completion, DefaultConfigurator configurator) { return new StandardWebSocketHandlerAdapter(handler, session -> createWebSocketSession(session, createHandshakeInfo(url, configurator), completion)); }
private HandshakeInfo createHandshakeInfo(URI url, DefaultConfigurator configurator) { HttpHeaders responseHeaders = configurator.getResponseHeaders(); String protocol = responseHeaders.getFirst("Sec-WebSocket-Protocol"); return new HandshakeInfo(url, responseHeaders, Mono.empty(), protocol); }
private HandshakeInfo createHandshakeInfo(URI url, DefaultNegotiation negotiation) { HttpHeaders responseHeaders = negotiation.getResponseHeaders(); String protocol = responseHeaders.getFirst("Sec-WebSocket-Protocol"); return new HandshakeInfo(url, responseHeaders, Mono.empty(), protocol); }
@Override protected StandardWebSocketSession createWebSocketSession(Session session, HandshakeInfo info, MonoProcessor<Void> completion) { return new TomcatWebSocketSession(session, info, bufferFactory(), completion); }
private Object createHandler(URI url, WebSocketHandler handler, MonoProcessor<Void> completion) { return new JettyWebSocketHandlerAdapter(handler, session -> { HandshakeInfo info = createHandshakeInfo(url, session); return new JettyWebSocketSession(session, info, this.bufferFactory, completion); }); }
private void handleChannel(URI url, WebSocketHandler handler, MonoProcessor<Void> completion, DefaultNegotiation negotiation, WebSocketChannel channel) { HandshakeInfo info = createHandshakeInfo(url, negotiation); UndertowWebSocketSession session = new UndertowWebSocketSession(channel, info, this.bufferFactory, completion); UndertowWebSocketHandlerAdapter adapter = new UndertowWebSocketHandlerAdapter(session); channel.getReceiveSetter().set(adapter); channel.resumeReceives(); handler.handle(session).subscribe(session); }