重新连接 OkHttp websocket 当互联网断开连接时

2022-09-04 23:15:54

我有以下课程。我正在尝试让 WebSocket 在发生故障时重新连接

public class WebSocketClient extends WebSocketListener {
    volatile OkHttpClient client;
    volatile WebSocket webSocket;
    volatile Boolean isConnected = false;

    public WebSocketClient() {
        Proxy proxy = null;

        if (Main.useProxy) {
            tinder.CustomProxy proxyCustom = ProxyManager.GetStaticProxy(ThreadLocalManager.account.get().getProxyId());
            proxy = new Proxy(Proxy.Type.HTTP,
                    new InetSocketAddress(proxyCustom.getProxyIp(), proxyCustom.getProxyPort()));
        }

        client = new OkHttpClient.Builder().proxy(proxy).readTimeout(2, TimeUnit.SECONDS)
                .connectTimeout(2, TimeUnit.SECONDS).build();


        Request request = new Request.Builder().url("wss://echo.com/ws")
                .addHeader("Accept-Language", "en").build();
        webSocket = client.newWebSocket(request, this);
    }

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        AnsiConsole.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Socket connection successful").reset());
        isConnected = true;
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
        System.out.println("Text MESSAGE: " + text);
    }

    @Override
    public void onMessage(WebSocket webSocket, ByteString bytes) {

    }

    @Override
    public void onClosing(WebSocket webSocket, int code, String reason) {
        webSocket.close(1000, null);
        System.out.println("CLOSE: " + code + " " + reason);
        isConnected = false;
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        isConnected = false;
        AnsiConsole.out
                .println(Ansi.ansi().fg(Ansi.Color.RED).a("Socket connection failed! will try to reconnect").reset());

        while (!isConnected) {
            try {
                AnsiConsole.out
                        .println(Ansi.ansi().fg(Ansi.Color.YELLOW).a("Waiting to try socket connection!").reset());
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            Request request = new Request.Builder().url("wss://echo.com/ws")
                    .addHeader("Accept-Language", "en").build();
            webSocket = client.newWebSocket(request, this);
        }

        if (isConnected) {
            AnsiConsole.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Socket connection successful").reset());
        }
    }

    public void close() {
        if (webSocket != null) {
            webSocket.close(1000, "Connection closed");
        }
        client.dispatcher().executorService().shutdown();
    }

}

问题是,如果尝试几次重新连接,则 onFailure 方法将被调用多次。导致多个 Web 套接字连接,而不是一个。

当网络袜子断开连接时,如何使单个连接重新连接?


答案 1
public class WebSocketClient extends WebSocketListener {
    volatile OkHttpClient client;
    volatile WebSocket webSocket;
    volatile Boolean isConnected = false;

    public WebSocketClient() {
        Proxy proxy = null;

        if (Main.useProxy) {
            tinder.CustomProxy proxyCustom = ProxyManager.GetStaticProxy(ThreadLocalManager.account.get().getProxyId());
            proxy = new Proxy(Proxy.Type.HTTP,
                    new InetSocketAddress(proxyCustom.getProxyIp(), proxyCustom.getProxyPort()));
        }

        client = new OkHttpClient.Builder().proxy(proxy).readTimeout(2, TimeUnit.SECONDS)
                .connectTimeout(2, TimeUnit.SECONDS).build();

        Request request = new Request.Builder().url("wss://echo.com/ws")
                .addHeader("Accept-Language", "en").build();
        webSocket = client.newWebSocket(request, this);

        // First Change
        client.connectionPool.evictAll();
    }

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        AnsiConsole.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Socket connection successful").reset());
        isConnected = true;
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
        System.out.println("Text MESSAGE: " + text);
    }

    @Override
    public void onMessage(WebSocket webSocket, ByteString bytes) {

    }

    @Override
    public void onClosing(WebSocket webSocket, int code, String reason) {
        webSocket.close(1000, null);
        System.out.println("CLOSE: " + code + " " + reason);
        isConnected = false;
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        // Second Change
        webSocket.close(1000, null);
        close();
        Thread.sleep(10000);

        Request request = new Request.Builder().url("wss://echo.com/ws")
                .addHeader("Accept-Language", "en").build();
        webSocket = client.newWebSocket(request, this);
    }

    public void close() {
        if (webSocket != null) {
            webSocket.close(1000, "Connection closed");
        }
    }
}

答案 2

对于多个空闲连接客户端,请提供一个connectionPool

client.connectionPool().evictAll();

该方法逐出所有连接。evictAll()


推荐