diff --git a/foudations/mogo-network/src/main/java/com/mogo/cloud/network/OkHttpFactory.kt b/foudations/mogo-network/src/main/java/com/mogo/cloud/network/OkHttpFactory.kt index 5372f92..fcc6bac 100644 --- a/foudations/mogo-network/src/main/java/com/mogo/cloud/network/OkHttpFactory.kt +++ b/foudations/mogo-network/src/main/java/com/mogo/cloud/network/OkHttpFactory.kt @@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit */ class OkHttpFactory private constructor() { companion object { + val okHttpClient: OkHttpClient by lazy { OkHttpClient.Builder() .addNetworkInterceptor(HttpHeaderInterceptor()) @@ -30,6 +31,7 @@ class OkHttpFactory private constructor() { .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS) .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS) .writeTimeout(WRITE_TIMEOUT, TimeUnit.MILLISECONDS) + .eventListenerFactory(WeakNetworkEventFactory.FACTORY) .build() } diff --git a/foudations/mogo-network/src/main/java/com/mogo/cloud/network/RetrofitFactory.kt b/foudations/mogo-network/src/main/java/com/mogo/cloud/network/RetrofitFactory.kt index d1a9fb4..6b35552 100644 --- a/foudations/mogo-network/src/main/java/com/mogo/cloud/network/RetrofitFactory.kt +++ b/foudations/mogo-network/src/main/java/com/mogo/cloud/network/RetrofitFactory.kt @@ -26,6 +26,7 @@ object RetrofitFactory { .addConverterFactory(GsonConverterFactory.create()) .build() sRpcServiceMap[baseUrl] = target + WeakNetworkEventFactory.setListener(WeakNetworkManager.listener) } return target } @@ -40,6 +41,7 @@ object RetrofitFactory { .addConverterFactory(GsonConverterFactory.create()) .build() sRpcNoAdapterServiceMap[baseUrl] = target + WeakNetworkEventFactory.setListener(WeakNetworkManager.listener) } return target } diff --git a/foudations/mogo-network/src/main/java/com/mogo/cloud/network/WeakNetworkEventFactory.kt b/foudations/mogo-network/src/main/java/com/mogo/cloud/network/WeakNetworkEventFactory.kt new file mode 100644 index 0000000..4e004e1 --- /dev/null +++ b/foudations/mogo-network/src/main/java/com/mogo/cloud/network/WeakNetworkEventFactory.kt @@ -0,0 +1,90 @@ +package com.mogo.cloud.network + +import okhttp3.* +import okhttp3.EventListener.Factory +import java.io.IOException +import java.net.InetAddress +import java.net.InetSocketAddress +import java.net.Proxy + +class WeakNetworkEventFactory { + companion object { + val FACTORY by lazy { + Factory { WeakNetworkEventListener() } + } + + private var listener: OnHttpRttListener? = null + + internal fun setListener(httpRttListener: OnHttpRttListener?) { + listener = httpRttListener + } + } + + private class WeakNetworkEventListener: EventListener() { + + private var timeStamp: Long = 0 + + override fun callStart(call: Call) { + super.callStart(call) + timeStamp = System.currentTimeMillis() + } + + override fun dnsStart(call: Call, domainName: String) { + super.dnsStart(call, domainName) + } + + override fun dnsEnd( + call: Call, + domainName: String, + inetAddressList: MutableList + ) { + super.dnsEnd(call, domainName, inetAddressList) + } + + override fun connectFailed( + call: Call, + inetSocketAddress: InetSocketAddress, + proxy: Proxy, + protocol: Protocol?, + ioe: IOException + ) { + super.connectFailed(call, inetSocketAddress, proxy, protocol, ioe) + listener?.onFailEvent(this.hashCode(), call.request().url().toString(), System.currentTimeMillis() - timeStamp) + } + + override fun responseHeadersStart(call: Call) { + super.responseHeadersStart(call) + } + + override fun responseHeadersEnd(call: Call, response: Response) { + super.responseHeadersEnd(call, response) + listener?.onHttpRttReceived(this.hashCode(), call.request().url().toString(), System.currentTimeMillis() - timeStamp) + } + + override fun responseBodyStart(call: Call) { + super.responseBodyStart(call) + } + + override fun responseBodyEnd(call: Call, byteCount: Long) { + super.responseBodyEnd(call, byteCount) + } + + override fun connectionReleased(call: Call, connection: Connection) { + super.connectionReleased(call, connection) + } + + override fun callFailed(call: Call, ioe: IOException) { + super.callFailed(call, ioe) + } + + override fun callEnd(call: Call) { + super.callEnd(call) + } + } + + internal interface OnHttpRttListener { + fun onHttpRttReceived(hashCode: Int, url: String, timeStamp: Long) + + fun onFailEvent(hashCode: Int, url: String, timeStamp: Long) + } +} \ No newline at end of file diff --git a/foudations/mogo-network/src/main/java/com/mogo/cloud/network/WeakNetworkManager.kt b/foudations/mogo-network/src/main/java/com/mogo/cloud/network/WeakNetworkManager.kt new file mode 100644 index 0000000..74db1b4 --- /dev/null +++ b/foudations/mogo-network/src/main/java/com/mogo/cloud/network/WeakNetworkManager.kt @@ -0,0 +1,84 @@ +package com.mogo.cloud.network + +import java.util.concurrent.locks.ReentrantReadWriteLock + +object WeakNetworkManager { + + private var weakHttpListener: OnWeakHttpListener? = null + + @Volatile + var WEAK_HTTP_RTT_THRESHOLD = 500 + + @Volatile + var FAILURE_THRESHOLD = 10 + + @Volatile + var isDebug = true + + private val lock by lazy { + ReentrantReadWriteLock() + } + private val writeLock by lazy { + lock.writeLock() + } + private val readLock by lazy { + lock.readLock() + } + + private var failCount = 0L + + fun setListener(weakHttpListener: OnWeakHttpListener?) { + this.weakHttpListener = weakHttpListener + } + + internal val listener = object : WeakNetworkEventFactory.OnHttpRttListener { + override fun onHttpRttReceived(hashCode: Int, url: String, timeStamp: Long) { + weakHttpListener?.onHttpRttReceived(hashCode, url, timeStamp) + if (timeStamp > WEAK_HTTP_RTT_THRESHOLD) { + weakHttpListener?.onWeakNetworkEvent() + } + } + + override fun onFailEvent(hashCode: Int, url: String, timeStamp: Long) { + val failCount = increment() + weakHttpListener?.onFailEvent(hashCode, url, timeStamp, failCount) + if (failCount >= FAILURE_THRESHOLD) { + clearFailCount() + weakHttpListener?.onWeakNetworkEvent() + } + } + } + + private fun increment(): Long { + writeLock.lock() + try { + return ++failCount + } finally { + writeLock.unlock() + } + } + + private fun clearFailCount() { + writeLock.lock() + try { + failCount = 0 + } finally { + writeLock.unlock() + } + } + + private fun getFailCount(): Long { + readLock.lock() + try { + return failCount + } finally { + readLock.unlock() + } + } + + interface OnWeakHttpListener { + fun onHttpRttReceived(hashCode: Int, url: String, timeStamp: Long) + fun onFailEvent(hashCode: Int, url: String, timeStamp: Long, currentFailCount: Long) + fun onWeakNetworkEvent() + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 73abba0..7ec2348 100644 --- a/gradle.properties +++ b/gradle.properties @@ -36,24 +36,24 @@ PASSWORD=xintai2018 RELEASE=true # AI CLOUD 云平台 # 工具类 -MOGO_UTILS_VERSION=1.4.7.8 +MOGO_UTILS_VERSION=1.4.7.9 # 网络请求 -MOGO_NETWORK_VERSION=1.4.7.8 +MOGO_NETWORK_VERSION=1.4.7.9 # 鉴权 -MOGO_PASSPORT_VERSION=1.4.7.8 +MOGO_PASSPORT_VERSION=1.4.7.9 # 常链接 -MOGO_SOCKET_VERSION=1.4.7.8 +MOGO_SOCKET_VERSION=1.4.7.9 # 数据采集 -MOGO_REALTIME_VERSION=1.4.7.8 +MOGO_REALTIME_VERSION=1.4.7.9 # 探路,道路事件发布,获取 -MOGO_TANLU_VERSION=1.4.7.8 +MOGO_TANLU_VERSION=1.4.7.9 # 直播推流 -MOGO_LIVE_VERSION=1.4.7.8 +MOGO_LIVE_VERSION=1.4.7.9 # 直播拉流 -MOGO_TRAFFICLIVE_VERSION=1.4.7.8 +MOGO_TRAFFICLIVE_VERSION=1.4.7.9 # 定位服务 -MOGO_LOCATION_VERSION=1.4.7.8 +MOGO_LOCATION_VERSION=1.4.7.9 # 远程通讯模块 -MOGO_TELEMATIC_VERSION=1.4.7.8 +MOGO_TELEMATIC_VERSION=1.4.7.9 # v2x -MOGO_V2X_VERSION=1.4.7.8 +MOGO_V2X_VERSION=1.4.7.9