All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mcollovati.vertx.vaadin.devserver.DevServerWebSocketProxy Maven / Gradle / Ivy

package com.github.mcollovati.vertx.vaadin.devserver;

import java.util.function.Supplier;

import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpClientOptions;
import io.vertx.core.http.ServerWebSocket;
import io.vertx.core.http.WebSocket;
import io.vertx.core.http.WebSocketConnectOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DevServerWebSocketProxy implements Handler {

    private static final Logger logger = LoggerFactory.getLogger(DevServerWebSocketProxy.class);

    private static final int DEFAULT_TIMEOUT = 120 * 1000;

    private Supplier> wsClientFactory;

    private DevServerWebSocketProxy(Supplier> wsClientFactory) {
        this.wsClientFactory = wsClientFactory;
    }

    @Override
    public void handle(ServerWebSocket browserSocket) {
        new Proxy(browserSocket, wsClientFactory.get());
    }

    private static class Proxy {
        private final ServerWebSocket browserSocket;
        private WebSocket devServerSocket;

        Proxy(ServerWebSocket browserSocket, Future devServerSocket) {
            Promise handshakePromise = Promise.promise();
            this.browserSocket = browserSocket;
            this.browserSocket.setHandshake(handshakePromise.future());
            this.browserSocket.textMessageHandler(this::sendToDevServer);
            this.browserSocket.closeHandler(closeEvent -> this.closeDevServerSession());

            devServerSocket.andThen(ev -> {
                if (ev.succeeded()) {
                    handshakePromise.complete(101);
                    this.devServerSocket = ev.result();
                    this.devServerSocket.textMessageHandler(this::sendToBrowser);
                    this.devServerSocket.closeHandler(unused -> this.closeBrowserSession());
                } else {
                    handshakePromise.fail(ev.cause());
                    logger.error("Cannot connect to Dev Server WebSocket", ev.cause());
                }
            });
        }

        private void sendToBrowser(String message) {
            if (browserSocket != null) {
                browserSocket.writeTextMessage(message, res -> {
                    if (res.succeeded()) {
                        logger.debug("Message sent to browser: {}", message);
                    } else {
                        logger.debug("Error sending message to browser: {}", message, res.cause());
                    }
                });
            } else {
                logger.debug("Cannot forward message to Browser because websocket is not ready: {}", message);
            }
        }

        private void closeBrowserSession() {
            if (browserSocket != null) {
                browserSocket.close(devServerSocket.closeStatusCode(), devServerSocket.closeReason());
            } else {
                logger.debug("Cannot close Browser websocket because it is not ready");
            }
        }

        private void sendToDevServer(String message) {
            if (devServerSocket != null) {
                devServerSocket.writeTextMessage(message, res -> {
                    if (res.succeeded()) {
                        logger.debug("Got message from browser: {}", message);
                    } else {
                        logger.debug("Error sending message to Dev Server: {}", message, res.cause());
                    }
                });
            } else {
                logger.debug("Cannot forward message to Dev Server because websocket is not ready: {}", message);
            }
        }

        private void closeDevServerSession() {
            if (devServerSocket != null) {
                devServerSocket.close();
            } else {
                logger.debug("Cannot close Dev Server websocket because it is not ready");
            }
        }
    }

    public static DevServerWebSocketProxy createWebsocketProxy(Vertx vertx, int port, String path) {
        HttpClientOptions options = new HttpClientOptions()
                .setLogActivity(true)
                .setConnectTimeout(DEFAULT_TIMEOUT)
                .setIdleTimeout(DEFAULT_TIMEOUT)
                .setDefaultHost("localhost")
                .setDefaultPort(port);
        WebSocketConnectOptions wsOptions =
                new WebSocketConnectOptions().addSubProtocol("vite-hmr").setURI(path);
        return new DevServerWebSocketProxy(() -> vertx.createHttpClient(options).webSocket(wsOptions));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy