okhttp 实现长连接的完整方案

OkHttp 天然支持 HTTP/1.x 的 Keep-Alive 和 HTTP/2 的多路复用,可以高效实现长连接通信。以下是针对 Android 与硬件通信的长连接实现细节:

WebSocket 长连接实现(全双工)

1. 完整 WebSocket 客户端

Kotlin 复制代码
object HardwareWebSocketManager {
    private val client = OkHttpClient.Builder()
        .pingInterval(20, TimeUnit.SECONDS)  // 自动Ping
        .retryOnConnectionFailure(true)
        .build()

    private var webSocket: WebSocket? = null

    fun connect(url: String, listener: WebSocketListener) {
        val request = Request.Builder()
            .url("ws://$url/control")
            .addHeader("Device-ID", getDeviceId())
            .build()
        
        webSocket = client.newWebSocket(request, object : WebSocketListener() {
            override fun onOpen(webSocket: WebSocket, response: Response) {
                // 连接成功
                listener.onOpen(webSocket, response)
                startHeartbeat()  // 启动自定义心跳
            }
            
            override fun onMessage(webSocket: WebSocket, text: String) {
                // 处理文本消息
                listener.onMessage(webSocket, text)
            }
            
            override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
                // 连接关闭
                listener.onClosed(webSocket, code, reason)
                cleanup()
            }
            
            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                // 连接失败
                listener.onFailure(webSocket, t, response)
                reconnect()  // 自动重连
            }
        })
    }

    private fun startHeartbeat() {
        // 自定义心跳实现
        val heartbeat = "{\"type\":\"heartbeat\"}"
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate({
            webSocket?.send(heartbeat)
        }, 15, 15, TimeUnit.SECONDS)
    }
}

二、HTTP 长轮询实现

1. 服务端推送模拟方案

Kotlin 复制代码
suspend fun startLongPolling() {
    val request = Request.Builder()
        .url("http://hardware-ip/long-polling")
        .header("Connection", "Keep-Alive")
        .build()

    while (isActive) {  // 使用协程保持长连接
        try {
            client.newCall(request).execute().use { response ->
                if (response.isSuccessful) {
                    processData(response.body?.string())
                }
            }
        } catch (e: IOException) {
            delay(5000)  // 失败后等待5秒重试
        }
    }
}

三、针对 WiFi 硬件的特殊优化

1. 本地网络加速配置

Kotlin 复制代码
val localOptimizedClient = OkHttpClient.Builder()
    .dns(object : Dns {
        override fun lookup(hostname: String): List<InetAddress> {
            // 优先返回本地IP
            return if (isLocalHardware(hostname)) {
                listOf(InetAddress.getByName("192.168.1.100"))
            } else {
                Dns.SYSTEM.lookup(hostname)
            }
        }
    })
    .socketFactory(createLowLatencySocketFactory())
    .build()

2. 连接状态监听

Kotlin 复制代码
.addNetworkInterceptor(object : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val connection = chain.connection()
        if (connection != null) {
            monitorConnectionState(connection)
        }
        return chain.proceed(chain.request())
    }
})

四、完整生命周期管理

1. 连接状态管理类

Kotlin 复制代码
class HardwareConnectionManager {
    private val clients = mutableMapOf<String, OkHttpClient>()
    
    fun getClient(key: String): OkHttpClient {
        return clients.getOrPut(key) {
            OkHttpClient.Builder().apply {
                // 公共配置
                connectionPool(ConnectionPool(3, 5, TimeUnit.MINUTES))
                // 根据key添加特殊配置
                when (key) {
                    "control" -> {
                        readTimeout(0, TimeUnit.SECONDS)
                        addInterceptor(ControlEncryptInterceptor())
                    }
                    "data" -> {
                        writeTimeout(0, TimeUnit.SECONDS)
                        addInterceptor(DataCompressionInterceptor())
                    }
                }
            }.build()
        }
    }
    
    fun cleanup() {
        clients.values.forEach { client ->
            client.dispatcher.executorService.shutdown()
            client.connectionPool.evictAll()
        }
        clients.clear()
    }
}

五、注意事项

  1. 资源消耗

    • 每个长连接会占用一个线程

    • 建议单个App不超过5个持久化长连接

  2. WiFi特性适配

    Kotlin 复制代码
    .socketFactory(createWiFiOptimizedSocketFactory())
    .addInterceptor(WiFiSignalInterceptor())
  3. 重连策略

    Kotlin 复制代码
    .addInterceptor(RetryInterceptor(
        maxRetries = 5,
        retryOnConnectionFailure = true,
        retryOnHttpCodes = listOf(502, 503, 504)
    ))
  4. Android特性适配

    • onPause()时降低心跳频率

    • onResume()时恢复活跃状态

    • onDestroy()时正确关闭连接

通过以上方案,您可以实现稳定可靠的硬件长连接通信,同时兼顾Android平台的特性要求。

相关推荐
消失的旧时光-19432 天前
OkHttp 中实现断点续传 demo
okhttp
Qian Xiaoo3 天前
Ajax入门
前端·ajax·okhttp
androidwork4 天前
OkHttp 3.0源码解析:从设计理念到核心实现
android·java·okhttp·kotlin
Lhuu(重开版5 天前
Vue:Ajax
vue.js·ajax·okhttp
知月玄6 天前
网页前端开发(基础进阶4--axios)
okhttp
余渔鱼11237 天前
ajax学习手册
学习·ajax·okhttp
smallluan8 天前
入门AJAX——XMLHttpRequest(Post)
前端·ajax·okhttp
志存高远6610 天前
(面试)OkHttp实现原理
okhttp
隐-梵11 天前
Android studio进阶开发(七)---做一个完整的登录系统(前后端连接)
android·数据库·ide·spring·okhttp·android studio