okhttp 实现长连接的完整方案
OkHttp 天然支持 HTTP/1.x 的 Keep-Alive 和 HTTP/2 的多路复用,可以高效实现长连接通信。以下是针对 Android 与硬件通信的长连接实现细节:
WebSocket 长连接实现(全双工)
1. 完整 WebSocket 客户端
object HardwareWebSocketManager {private val client = OkHttpClient.Builder().pingInterval(20, TimeUnit.SECONDS) // 自动Ping.retryOnConnectionFailure(true).build()private var webSocket: WebSocket? = nullfun 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. 服务端推送模拟方案
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. 本地网络加速配置
val localOptimizedClient = OkHttpClient.Builder().dns(object : Dns {override fun lookup(hostname: String): List<InetAddress> {// 优先返回本地IPreturn if (isLocalHardware(hostname)) {listOf(InetAddress.getByName("192.168.1.100"))} else {Dns.SYSTEM.lookup(hostname)}}}).socketFactory(createLowLatencySocketFactory()).build()
2. 连接状态监听
.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. 连接状态管理类
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()}
}
五、注意事项
-
资源消耗:
-
每个长连接会占用一个线程
-
建议单个App不超过5个持久化长连接
-
-
WiFi特性适配:
.socketFactory(createWiFiOptimizedSocketFactory()) .addInterceptor(WiFiSignalInterceptor())
-
重连策略:
.addInterceptor(RetryInterceptor(maxRetries = 5,retryOnConnectionFailure = true,retryOnHttpCodes = listOf(502, 503, 504) ))
-
Android特性适配:
-
在
onPause()
时降低心跳频率 -
在
onResume()
时恢复活跃状态 -
在
onDestroy()
时正确关闭连接
-
通过以上方案,您可以实现稳定可靠的硬件长连接通信,同时兼顾Android平台的特性要求。