ws 重连退避

本文介绍了如何使用OkHttp库在Java中实现WebSocket的自动重连功能,包括使用ReconnectingWebSocketListener进行重试连接,以及利用ScheduledExecutorService进行定时任务的调度。
摘要由CSDN通过智能技术生成

一、退避重连

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

public class ReconnectingWebSocketListener extends WebSocketListener {
    private static final int MAX_RECONNECT_ATTEMPTS = 5;
    private static final long INITIAL_RECONNECT_DELAY = 1000; // 初始重连延迟(毫秒)

    private WebSocket webSocket;
    private final String url;
    private int reconnectAttempts;

    public ReconnectingWebSocketListener(String url) {
        this.url = url;
        this.reconnectAttempts = 0;
    }

    @Override
    public void onOpen(WebSocket webSocket, okhttp3.Response response) {
        this.webSocket = webSocket;
        reconnectAttempts = 0;
        // 连接成功后的处理
    }

    @Override
    public void onClosed(WebSocket webSocket, int code, String reason) {
        this.webSocket = null;
        if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
            reconnectAttempts++;
            long delay = calculateDelay(reconnectAttempts);
            scheduleReconnect(delay);
        } else {
            // 达到最大重连次数,停止重连
        }
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, okhttp3.Response response) {
        this.webSocket = null;
        if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
            reconnectAttempts++;
            long delay = calculateDelay(reconnectAttempts);
            scheduleReconnect(delay);
        } else {
            // 达到最大重连次数,停止重连
        }
    }

    private long calculateDelay(int attempts) {
        // 使用指数退避策略,计算下一次重连的延迟
        return INITIAL_RECONNECT_DELAY * (long) Math.pow(2, attempts - 1);
    }

    private void scheduleReconnect(long delay) {
        new Thread(() -> {
            try {
                Thread.sleep(delay);
                reconnect();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }

    private void reconnect() {
        OkHttpClient client = new OkHttpClient.Builder().build();
        Request request = new Request.Builder().url(url).build();
        client.newWebSocket(request, this);
    }

    // 其他回调方法...

    public static void main(String[] args) {
        String websocketUrl = "ws://your.websocket.url";
        ReconnectingWebSocketListener listener = new ReconnectingWebSocketListener(websocketUrl);

        OkHttpClient client = new OkHttpClient.Builder().build();
        Request request = new Request.Builder().url(websocketUrl).build();
        client.newWebSocket(request, listener);
    }
}

二、重连

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

import java.io.EOFException;

public class ReconnectingWebSocketExample {

    private static final String WS_URL = "your_websocket_url";
    private static final long RECONNECT_DELAY_MS = 5000; // 重连延迟时间,单位毫秒

    private OkHttpClient client;
    private WebSocket webSocket;
    private WebSocketListener webSocketListener;

    public ReconnectingWebSocketExample() {
        client = new OkHttpClient();
        createWebSocket();
    }

    private void createWebSocket() {
        Request request = new Request.Builder()
                .url(WS_URL)
                .build();

        webSocketListener = new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                System.out.println("WebSocket opened");
            }

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

            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                System.out.println("Received bytes: " + bytes.hex());
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                if (t instanceof EOFException) {
                    System.out.println("WebSocket connection closed");
                    // 触发重连
                    reconnect();
                } else {
                    t.printStackTrace();
                }
            }
        };

        webSocket = client.newWebSocket(request, webSocketListener);
    }

    private void reconnect() {
        // 关闭旧的WebSocket连接
        webSocket.cancel();

        // 延迟一段时间后重新创建WebSocket连接
        new Thread(() -> {
            try {
                Thread.sleep(RECONNECT_DELAY_MS);
                createWebSocket();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }

    public static void main(String[] args) {
        new ReconnectingWebSocketExample();
    }
}


三、定时器

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class RestartableScheduledTask {

    private static ScheduledExecutorService scheduler;
    private static Runnable task;

    public static void main(String[] args) {
        // 创建ScheduledExecutorService
        scheduler = Executors.newScheduledThreadPool(1);

        // 创建定时任务
        task = () -> {
            // 定时任务要执行的操作
            System.out.println("定时任务执行了!");
        };

        // 启动定时任务
        startScheduledTask();

        // 让程序运行一段时间,以便你能看到定时任务的执行
        try {
            Thread.sleep(5000); // 5秒后重新启动定时任务
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 重新启动定时任务
        restartScheduledTask();

        // 让程序再次运行一段时间
        try {
            Thread.sleep(5000); // 5秒后停止定时任务
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 停止定时任务
        stopScheduledTask();
    }

    private static void startScheduledTask() {
        // 启动定时任务,每隔1秒执行一次
        scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
    }

    private static void restartScheduledTask() {
        // 取消之前的任务
        scheduler.shutdown();

        // 创建一个新的ScheduledExecutorService
        scheduler = Executors.newScheduledThreadPool(1);

        // 启动新的定时任务
        startScheduledTask();
    }

    private static void stopScheduledTask() {
        // 关闭ScheduledExecutorService
        scheduler.shutdown();
    }
}

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值