You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用okhttp3.Interceptor捕获okhttp3 WebSocket网络活动?

解决OkHttp3 WebSocket无法用普通Interceptor捕获全部网络活动的问题

我刚好之前研究过OkHttp WebSocket的拦截器问题,这其实是OkHttp拦截器体系的设计逻辑导致的——普通的Interceptor只能处理WebSocket初始化阶段的HTTP Upgrade握手请求,但无法捕获握手完成后WebSocket协议的帧通信(文本、二进制消息等)。下面具体解释原因和解决方案:

为什么普通Interceptor不生效?

OkHttp的Interceptor体系是为标准HTTP请求/响应设计的:

  • 当你创建WebSocket连接时,第一步会发送一个GET请求并携带Upgrade: websocket等头部,这个HTTP请求确实会经过你添加的拦截器链,你可以捕获到这个握手请求和对应的101响应。
  • 但一旦握手成功,连接就切换到了WebSocket协议的帧通信模式,这部分通信不再经过HTTP拦截器链,所以你看不到后续的消息收发活动。

验证:Interceptor能捕获握手请求

你可以运行下面的代码,会发现拦截器确实打印了握手阶段的请求和响应,但后续的WebSocket消息不会被拦截:

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(chain -> {
        Request request = chain.request();
        System.out.println("[Interceptor] 捕获请求: " + request.method() + " " + request.url());
        Response response = chain.proceed(request);
        System.out.println("[Interceptor] 捕获响应: " + response.code() + " " + response.message());
        return response;
    })
    .build();

Request wsRequest = new Request.Builder()
    .url("ws://your-websocket-endpoint")
    .build();

client.newWebSocket(wsRequest, new WebSocketListener() {
    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
        System.out.println("[WebSocket] 连接已打开");
        webSocket.send("Hello from client");
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
        super.onMessage(webSocket, text);
        System.out.println("[WebSocket] 收到消息: " + text);
    }
});

正确监控WebSocket全流程的方案

如果需要捕获WebSocket的所有网络活动(握手+消息收发+关闭),可以用以下两种方法:

方法1:自定义WebSocketListener

WebSocketListener是OkHttp专门为WebSocket事件设计的回调类,重写它的方法可以监控所有关键节点:

class MonitoringWebSocketListener extends WebSocketListener {
    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        System.out.println("[WS监控] 握手完成,响应码: " + response.code());
        // 可以记录握手响应的头部等信息
        System.out.println("[WS监控] 响应头部: " + response.headers());
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
        System.out.println("[WS监控] 收到文本消息: " + text);
    }

    @Override
    public void onMessage(WebSocket webSocket, ByteString bytes) {
        System.out.println("[WS监控] 收到二进制消息,长度: " + bytes.size());
    }

    @Override
    public void onClosing(WebSocket webSocket, int code, String reason) {
        System.out.println("[WS监控] 连接正在关闭,code: " + code + ", reason: " + reason);
    }

    @Override
    public void onClosed(WebSocket webSocket, int code, String reason) {
        System.out.println("[WS监控] 连接已关闭,code: " + code + ", reason: " + reason);
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        System.err.println("[WS监控] 连接失败,异常: " + t.getMessage());
        if (response != null) {
            System.err.println("[WS监控] 失败响应: " + response.code());
        }
    }
}

// 使用这个自定义Listener
client.newWebSocket(wsRequest, new MonitoringWebSocketListener());

方法2:使用OkHttp EventListener

EventListener是OkHttp的全局事件监听器,可以监控包括HTTP请求、WebSocket在内的所有OkHttp活动,适合需要统一监控所有网络操作的场景:

class GlobalNetworkEventListener extends EventListener {
    @Override
    public void webSocketHandshakeStart(Call call, Request request) {
        System.out.println("[全局监控] WebSocket握手开始,请求: " + request.url());
    }

    @Override
    public void webSocketHandshakeEnd(Call call, Request request, Response response) {
        System.out.println("[全局监控] WebSocket握手结束,响应码: " + response.code());
    }

    @Override
    public void webSocketOpen(Call call, WebSocket webSocket) {
        System.out.println("[全局监控] WebSocket连接打开");
    }

    @Override
    public void webSocketMessage(Call call, WebSocket webSocket, String text) {
        System.out.println("[全局监控] WebSocket收到文本消息: " + text);
    }

    @Override
    public void webSocketMessage(Call call, WebSocket webSocket, ByteString bytes) {
        System.out.println("[全局监控] WebSocket收到二进制消息,长度: " + bytes.size());
    }

    @Override
    public void webSocketClosing(Call call, WebSocket webSocket, int code, String reason) {
        System.out.println("[全局监控] WebSocket正在关闭,code: " + code + ", reason: " + reason);
    }

    @Override
    public void webSocketClosed(Call call, WebSocket webSocket, int code, String reason) {
        System.out.println("[全局监控] WebSocket已关闭,code: " + code + ", reason: " + reason);
    }

    @Override
    public void webSocketFailure(Call call, WebSocket webSocket, Throwable t, Response response) {
        System.err.println("[全局监控] WebSocket失败,异常: " + t.getMessage());
        if (response != null) {
            System.err.println("[全局监控] 失败响应: " + response.code());
        }
    }
}

// 给OkHttpClient添加全局EventListener
OkHttpClient client = new OkHttpClient.Builder()
    .eventListener(new GlobalNetworkEventListener())
    .build();

总结

  • 普通Interceptor仅能捕获WebSocket的HTTP握手请求,无法监控后续的帧通信;
  • 要完整监控WebSocket的所有网络活动,优先选择自定义WebSocketListener(专注WebSocket事件)或EventListener(全局网络监控)。

内容的提问来源于stack exchange,提问作者Rawnald Gregory Erickson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:53:04