@Override public Mono<Void> execute(URI url, HttpHeaders requestHeaders, WebSocketHandler handler) { return getHttpClient() .headers(nettyHeaders -> setNettyHeaders(requestHeaders, nettyHeaders)) .websocket(StringUtils.collectionToCommaDelimitedString(handler.getSubProtocols())) .uri(url.toString()) .handle((inbound, outbound) -> { HttpHeaders responseHeaders = toHttpHeaders(inbound); String protocol = responseHeaders.getFirst("Sec-WebSocket-Protocol"); HandshakeInfo info = new HandshakeInfo(url, responseHeaders, Mono.empty(), protocol); NettyDataBufferFactory factory = new NettyDataBufferFactory(outbound.alloc()); WebSocketSession session = new ReactorNettyWebSocketSession(inbound, outbound, info, factory); if (logger.isDebugEnabled()) { logger.debug("Started session '" + session.getId() + "' for " + url); } return handler.handle(session); }) .doOnRequest(n -> { if (logger.isDebugEnabled()) { logger.debug("Connecting to " + url); } }) .next(); }
@OnWebSocketConnect public void onWebSocketConnect(Session session) { this.delegateSession = this.sessionFactory.apply(session); this.delegateHandler.handle(this.delegateSession).subscribe(this.delegateSession); }
@Nullable private String selectProtocol(HttpHeaders headers, WebSocketHandler handler) { String protocolHeader = headers.getFirst(SEC_WEBSOCKET_PROTOCOL); if (protocolHeader != null) { List<String> supportedProtocols = handler.getSubProtocols(); for (String protocol : StringUtils.commaDelimitedListToStringArray(protocolHeader)) { if (supportedProtocols.contains(protocol)) { return protocol; } } } return null; }
@Override public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler, @Nullable String subProtocol, Supplier<HandshakeInfo> handshakeInfoFactory) { ServerHttpResponse response = exchange.getResponse(); HttpServerResponse reactorResponse = ((AbstractServerHttpResponse) response).getNativeResponse(); HandshakeInfo handshakeInfo = handshakeInfoFactory.get(); NettyDataBufferFactory bufferFactory = (NettyDataBufferFactory) response.bufferFactory(); return reactorResponse.sendWebsocket(subProtocol, this.maxFramePayloadLength, (in, out) -> { ReactorNettyWebSocketSession session = new ReactorNettyWebSocketSession( in, out, handshakeInfo, bufferFactory, this.maxFramePayloadLength); return handler.handle(session); }); }
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); }
@Override public void onConnect(WebSocketHttpExchange httpExchange, WebSocketChannel channel) { UndertowWebSocketSession session = createSession(channel); UndertowWebSocketHandlerAdapter adapter = new UndertowWebSocketHandlerAdapter(session); channel.getReceiveSetter().set(adapter); channel.resumeReceives(); this.handler.handle(session).subscribe(session); }
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); }
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); }
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); }
@Override public void onOpen(Session session, EndpointConfig config) { this.delegateSession = this.sessionFactory.apply(session); Assert.state(this.delegateSession != null, "No delegate session"); session.addMessageHandler(String.class, message -> { WebSocketMessage webSocketMessage = toMessage(message); this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); }); session.addMessageHandler(ByteBuffer.class, message -> { WebSocketMessage webSocketMessage = toMessage(message); this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); }); session.addMessageHandler(PongMessage.class, message -> { WebSocketMessage webSocketMessage = toMessage(message); this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); }); this.delegateHandler.handle(this.delegateSession).subscribe(this.delegateSession); }
protected String[] beforeHandshake(URI url, HttpHeaders requestHeaders, WebSocketHandler handler) { if (logger.isDebugEnabled()) { logger.debug("Executing handshake to " + url); } return handler.getSubProtocols(); }
@OnWebSocketConnect public void onWebSocketConnect(Session session) { this.delegateSession = sessionFactory.apply(session); this.delegateHandler.handle(this.delegateSession).subscribe(this.delegateSession); }
private Optional<String> selectProtocol(HttpHeaders headers, WebSocketHandler handler) { String protocolHeader = headers.getFirst(SEC_WEBSOCKET_PROTOCOL); if (protocolHeader == null) { return Optional.empty(); } String[] protocols = handler.getSubProtocols(); return StringUtils.commaDelimitedListToSet(protocolHeader).stream() .filter(protocol -> Arrays.stream(protocols).anyMatch(protocol::equals)) .findFirst(); }
@Override public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler, Optional<String> subProtocol) { ReactorServerHttpResponse response = (ReactorServerHttpResponse) exchange.getResponse(); HandshakeInfo info = getHandshakeInfo(exchange, subProtocol); NettyDataBufferFactory bufferFactory = (NettyDataBufferFactory) response.bufferFactory(); return response.getReactorResponse().sendWebsocket(subProtocol.orElse(null), (in, out) -> handler.handle( new ReactorNettyWebSocketSession(in, out, info, bufferFactory))); }
@Override public void onConnect(WebSocketHttpExchange httpExchange, WebSocketChannel channel) { UndertowWebSocketSession session = createSession(channel); UndertowWebSocketHandlerAdapter adapter = new UndertowWebSocketHandlerAdapter(session); channel.getReceiveSetter().set(adapter); channel.resumeReceives(); this.handler.handle(session).subscribe(session); }
private void handleChannel(URI url, WebSocketHandler handler, MonoProcessor<Void> completion, DefaultNegotiation negotiation, WebSocketChannel channel) { HandshakeInfo info = afterHandshake(url, negotiation.getResponseHeaders()); UndertowWebSocketSession session = new UndertowWebSocketSession(channel, info, bufferFactory, completion); UndertowWebSocketHandlerAdapter adapter = new UndertowWebSocketHandlerAdapter(session); channel.getReceiveSetter().set(adapter); channel.resumeReceives(); handler.handle(session).subscribe(session); }
@Override public Mono<Void> execute(URI url, HttpHeaders headers, WebSocketHandler handler) { String[] protocols = beforeHandshake(url, headers, handler); // TODO: https://github.com/reactor/reactor-netty/issues/20 return getHttpClient() .get(url.toString(), request -> addHeaders(request, headers).sendWebsocket()) .then(response -> { HandshakeInfo info = afterHandshake(url, toHttpHeaders(response)); ByteBufAllocator allocator = response.channel().alloc(); NettyDataBufferFactory factory = new NettyDataBufferFactory(allocator); return response.receiveWebsocket((in, out) -> { WebSocketSession session = new ReactorNettyWebSocketSession(in, out, info, factory); return handler.handle(session); }); }); }
@Override public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler, Optional<String> subProtocol) { RxNettyServerHttpResponse response = (RxNettyServerHttpResponse) exchange.getResponse(); HttpServerResponse<?> rxNettyResponse = response.getRxNettyResponse(); HandshakeInfo info = getHandshakeInfo(exchange, subProtocol); NettyDataBufferFactory factory = (NettyDataBufferFactory) response.bufferFactory(); WebSocketHandshaker handshaker = rxNettyResponse .acceptWebSocketUpgrade(conn -> { RxNettyWebSocketSession session = new RxNettyWebSocketSession(conn, info, factory); String name = HttpHandlerNames.WsServerDecoder.getName(); session.aggregateFrames(rxNettyResponse.unsafeNettyChannel(), name); return RxReactiveStreams.toObservable(handler.handle(session)); }); if (subProtocol.isPresent()) { handshaker = handshaker.subprotocol(subProtocol.get()); } else { // TODO: https://github.com/reactor/reactor-netty/issues/20 handshaker = handshaker.subprotocol(new String[0]); } return Mono.from(RxReactiveStreams.toPublisher(handshaker)); }
private Observable<Void> executeInternal(URI url, HttpHeaders headers, WebSocketHandler handler) { String[] protocols = beforeHandshake(url, headers, handler); return createRequest(url, headers, protocols) .flatMap(response -> { Observable<WebSocketConnection> conn = response.getWebSocketConnection(); return Observable.zip(Observable.just(response), conn, Tuples::of); }) .flatMap(tuple -> { WebSocketResponse<ByteBuf> response = tuple.getT1(); WebSocketConnection conn = tuple.getT2(); HandshakeInfo info = afterHandshake(url, toHttpHeaders(response)); ByteBufAllocator allocator = response.unsafeNettyChannel().alloc(); NettyDataBufferFactory factory = new NettyDataBufferFactory(allocator); RxNettyWebSocketSession session = new RxNettyWebSocketSession(conn, info, factory); session.aggregateFrames(response.unsafeNettyChannel(), WsClientDecoder.getName()); return RxReactiveStreams.toObservable(handler.handle(session)); }); }
@Override public void onOpen(Session session, EndpointConfig config) { this.delegateSession = this.sessionFactory.apply(session); session.addMessageHandler(String.class, message -> { WebSocketMessage webSocketMessage = toMessage(message); this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); }); session.addMessageHandler(ByteBuffer.class, message -> { WebSocketMessage webSocketMessage = toMessage(message); this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); }); session.addMessageHandler(PongMessage.class, message -> { WebSocketMessage webSocketMessage = toMessage(message); this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); }); this.delegateHandler.handle(this.delegateSession).subscribe(this.delegateSession); }