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); }); }
@Override protected boolean sendMessage(WebSocketMessage message) throws IOException { ByteBuffer buffer = message.getPayload().asByteBuffer(); if (WebSocketMessage.Type.TEXT.equals(message.getType())) { getSendProcessor().setReadyToSend(false); String text = new String(buffer.array(), StandardCharsets.UTF_8); getDelegate().getRemote().sendString(text, new SendProcessorCallback()); } else if (WebSocketMessage.Type.BINARY.equals(message.getType())) { getSendProcessor().setReadyToSend(false); getDelegate().getRemote().sendBytes(buffer, new SendProcessorCallback()); } else if (WebSocketMessage.Type.PING.equals(message.getType())) { getDelegate().getRemote().sendPing(buffer); } else if (WebSocketMessage.Type.PONG.equals(message.getType())) { getDelegate().getRemote().sendPong(buffer); } else { throw new IllegalArgumentException("Unexpected message type: " + message.getType()); } return true; }
@OnWebSocketClose public void onWebSocketClose(int statusCode, String reason) { if (this.delegateSession != null) { this.delegateSession.handleClose(new CloseStatus(statusCode, reason)); } }
@OnWebSocketMessage public void onWebSocketBinary(byte[] message, int offset, int length) { if (this.delegateSession != null) { ByteBuffer buffer = ByteBuffer.wrap(message, offset, length); WebSocketMessage webSocketMessage = toMessage(Type.BINARY, buffer); this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); } }
@Override public void writeSuccess() { getSendProcessor().setReadyToSend(true); getSendProcessor().onWritePossible(); }
@Override protected void suspendReceiving() { Assert.state(this.suspendToken == null, "Already suspended"); this.suspendToken = getDelegate().suspend(); }
@OnWebSocketError public void onWebSocketError(Throwable cause) { if (this.delegateSession != null) { this.delegateSession.handleError(cause); } }
@OnWebSocketMessage public void onWebSocketText(String message) { if (this.delegateSession != null) { WebSocketMessage webSocketMessage = toMessage(Type.TEXT, message); this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); } }
@Override public void writeFailed(Throwable x) { getSendProcessor().cancel(); getSendProcessor().onError(x); }
@Override public Mono<Void> close(CloseStatus status) { getDelegate().close(status.getCode(), status.getReason()); return Mono.empty(); }
@OnWebSocketError public void onWebSocketError(Throwable cause) { if (this.delegateSession != null) { this.delegateSession.handleError(cause); } }
@Override protected boolean sendMessage(WebSocketMessage message) throws IOException { ByteBuffer buffer = message.getPayload().asByteBuffer(); if (WebSocketMessage.Type.TEXT.equals(message.getType())) { getSendProcessor().setReadyToSend(false); String text = new String(buffer.array(), StandardCharsets.UTF_8); getDelegate().getRemote().sendString(text, new SendProcessorCallback()); } else if (WebSocketMessage.Type.BINARY.equals(message.getType())) { getSendProcessor().setReadyToSend(false); getDelegate().getRemote().sendBytes(buffer, new SendProcessorCallback()); } else if (WebSocketMessage.Type.PING.equals(message.getType())) { getDelegate().getRemote().sendPing(buffer); } else if (WebSocketMessage.Type.PONG.equals(message.getType())) { getDelegate().getRemote().sendPong(buffer); } else { throw new IllegalArgumentException("Unexpected message type: " + message.getType()); } return true; }
@OnWebSocketFrame public void onWebSocketFrame(Frame frame) { if (this.delegateSession != null) { if (OpCode.PONG == frame.getOpCode()) { ByteBuffer buffer = (frame.getPayload() != null ? frame.getPayload() : EMPTY_PAYLOAD); WebSocketMessage webSocketMessage = toMessage(Type.PONG, buffer); this.delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); } } }
@Override public void writeFailed(Throwable x) { getSendProcessor().cancel(); getSendProcessor().onError(x); }
@Override public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler, @Nullable String subProtocol, Supplier<HandshakeInfo> handshakeInfoFactory) { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); HttpServletRequest servletRequest = getHttpServletRequest(request); HttpServletResponse servletResponse = getHttpServletResponse(response); HandshakeInfo handshakeInfo = handshakeInfoFactory.get(); DataBufferFactory factory = response.bufferFactory(); JettyWebSocketHandlerAdapter adapter = new JettyWebSocketHandlerAdapter( handler, session -> new JettyWebSocketSession(session, handshakeInfo, factory)); startLazily(servletRequest); Assert.state(this.factory != null, "No WebSocketServerFactory available"); boolean isUpgrade = this.factory.isUpgradeRequest(servletRequest, servletResponse); Assert.isTrue(isUpgrade, "Not a WebSocket handshake"); try { adapterHolder.set(new WebSocketHandlerContainer(adapter, subProtocol)); this.factory.acceptWebSocket(servletRequest, servletResponse); } catch (IOException ex) { return Mono.error(ex); } finally { adapterHolder.remove(); } return Mono.empty(); }
@Override public Mono<Void> close(CloseStatus status) { getDelegate().close(status.getCode(), status.getReason()); return Mono.empty(); }
@OnWebSocketClose public void onWebSocketClose(int statusCode, String reason) { if (this.delegateSession != null) { this.delegateSession.handleClose(new CloseStatus(statusCode, reason)); } }
@OnWebSocketMessage public void onWebSocketBinary(byte[] message, int offset, int length) { if (this.delegateSession != null) { ByteBuffer buffer = ByteBuffer.wrap(message, offset, length); WebSocketMessage webSocketMessage = toMessage(Type.BINARY, buffer); delegateSession.handleMessage(webSocketMessage.getType(), webSocketMessage); } }
@Override public void writeSuccess() { getSendProcessor().setReadyToSend(true); getSendProcessor().onWritePossible(); }
private Object createJettyHandler(URI url, WebSocketHandler handler, MonoProcessor<Void> completion) { return new JettyWebSocketHandlerAdapter(handler, session -> { UpgradeResponse response = session.getUpgradeResponse(); HttpHeaders responseHeaders = new HttpHeaders(); response.getHeaders().forEach(responseHeaders::put); HandshakeInfo info = afterHandshake(url, responseHeaders); return new JettyWebSocketSession(session, info, this.bufferFactory, completion); }); }