【问题标题】:How to catch okhttp3 WebSocket network activity using okhttp3.Interceptor?如何使用 okhttp3.Interceptor 捕获 okhttp3 WebSocket 网络活动?
【发布时间】:2018-07-29 02:24:18
【问题描述】:

我有一个 okhttp3 (3.9.1) WebSocket 实例,想查看它的所有网络请求和响应。在创建WebSocket 之前,我尝试将一些okhttp3.Interceptor 实例添加到OkHttpClient 实例,但在查看网络活动时没有运气。这是演示我尝试做的示例代码:

package sample

import okhttp3.*
import java.io.IOException
import java.lang.Thread.sleep

fun main(args: Array<String>) {
    val listener = object : WebSocketListener() {
        override fun onMessage(webSocket: WebSocket?, text: String?) {
            println("Got server message: $text")
        }
    }

    val dummyInterceptor = Interceptor { chain ->
        val request = chain.request()
        val response = chain.proceed(request)
        println("Dummy interceptor fired!\n\nRequest: ${request.headers()}\nResponse: ${response.headers()}")
        return@Interceptor response
    }

    val dummyNetworkInterceptor = Interceptor { chain ->
        val request = chain.request()
        val response = chain.proceed(request)
        println("Dummy network interceptor fired!\n\nRequest: ${request.headers()}\nResponse: ${response.headers()}")
        return@Interceptor response
    }

    val okHttpClient = OkHttpClient.Builder()
            .addInterceptor(dummyInterceptor)
            .addNetworkInterceptor(dummyNetworkInterceptor)
            .build()

    val request = Request.Builder().url("ws://echo.websocket.org").build()

    val webSocket = okHttpClient.newWebSocket(request, listener)

    webSocket.send("Hello1!")
    webSocket.send("Hello2!")
    webSocket.send("Hello3!")

    sleep(2000) //Just for this sample to ensure all WS requests done
    println("\n\n\tSome network activity\n\n")

    okHttpClient.newCall(Request.Builder().get().url("http://echo.websocket.org").build()).enqueue(object : Callback {
        override fun onFailure(call: Call?, exc: IOException?) {
            println("OnFailure: ${exc?.message}")
        }

        override fun onResponse(call: Call?, response: Response?) {
            println("OnResponse: ${response?.headers()}")
        }
    })
}

我试图深入研究 okhttp3 源代码,但没有找到任何理由说明为什么我的任何拦截器都不会在 WS 请求上触发但对任何 OkHttpClient 请求都非常有效。

这是 okhttp3 中的错误还是我做错了什么或者无法使用 okhttp3.Interceptor 监控 WS 请求?

【问题讨论】:

    标签: websocket kotlin okhttp3


    【解决方案1】:

    使用 OkHttp 进行的 WebSocket 调用不使用 HTTP 调用使用的拦截器链,因此您无法通过拦截器对其进行监控。

    我之前也遇到过这个问题,所以我查看了源代码,然后发现如下:

    • 常规的 HTTP 调用通过 RealCall 类中的 getResponseWithInterceptorChain() 方法,这很清楚地启动了每个请求的拦截器的链式调用。
    • 包含 WebSocket 处理实现的 okhttp3.internal.ws 包不包含与拦截器相关的代码。

    实际上,拦截 WebSocket 请求的拦截器一开始并没有什么意义。可以在拦截器中获取的Request代表一个HTTP请求,WebSocket messages are not

    【讨论】:

    • 所以......甚至无法通过 websocket 记录请求和响应?
    • @amitav13 您始终可以围绕您的 WS 实例构建一个包装器,并在 application 级别(即内部 ping 除外)记录或拦截通过它的所有请求和响应。我的问题是关于使用现有的内置 OkHttp 拦截器在 network 级别拦截此类调用。
    【解决方案2】:

    目前不可能,有一个针对 OkHttp 的功能请求开放,但没有得到太大的吸引力:https://github.com/square/okhttp/issues/4192

    【讨论】:

      猜你喜欢
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      • 2017-12-04
      • 2017-01-17
      • 2018-01-28
      • 1970-01-01
      • 2019-12-18
      相关资源
      最近更新 更多