Commit b9828bfe authored by chenhuaqing's avatar chenhuaqing Committed by hanakeichen

fix test latency

parent 38f8993c
...@@ -34,5 +34,5 @@ class AccVpnService { ...@@ -34,5 +34,5 @@ class AccVpnService {
} }
interface TestLatencyCallback { interface TestLatencyCallback {
fun onLatency(latency: Int) fun onLatency(latency: Int): Boolean
} }
\ No newline at end of file
...@@ -17,8 +17,8 @@ object NetworkAdapter { ...@@ -17,8 +17,8 @@ object NetworkAdapter {
var wifiNetwork: Network? = null var wifiNetwork: Network? = null
var cellularNetwork: Network? = null var cellularNetwork: Network? = null
var bindNetwork: Network? = null
private var bindNetwork: Network? = null
private val FD_FIELD: Field private val FD_FIELD: Field
val wifiRequest: NetworkRequest = NetworkRequest.Builder() val wifiRequest: NetworkRequest = NetworkRequest.Builder()
......
package com.github.shadowsocks.bg package com.github.shadowsocks.bg
import android.net.Network import android.net.Network
import android.os.Build
import com.ccnet.acc.AccVpn import com.ccnet.acc.AccVpn
import com.ccnet.acc.NetworkAdapter import com.ccnet.acc.NetworkAdapter
import com.github.shadowsocks.Core import com.github.shadowsocks.Core
...@@ -10,7 +9,6 @@ import com.github.shadowsocks.database.ProfileManager ...@@ -10,7 +9,6 @@ import com.github.shadowsocks.database.ProfileManager
import com.github.shadowsocks.http.* import com.github.shadowsocks.http.*
import com.github.shadowsocks.preference.DataStore import com.github.shadowsocks.preference.DataStore
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonStreamParser
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.tencent.mmkv.MMKV import com.tencent.mmkv.MMKV
import kotlinx.coroutines.* import kotlinx.coroutines.*
...@@ -20,8 +18,8 @@ import okhttp3.Request ...@@ -20,8 +18,8 @@ import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import timber.log.Timber import timber.log.Timber
import java.io.File
import java.io.IOException import java.io.IOException
import java.net.InetAddress
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.net.Socket import java.net.Socket
import java.security.SecureRandom import java.security.SecureRandom
...@@ -39,7 +37,7 @@ object AuthManager { ...@@ -39,7 +37,7 @@ object AuthManager {
var scheduleAtFixedRate: ScheduledFuture<*>? = null var scheduleAtFixedRate: ScheduledFuture<*>? = null
var scheduleAtFixedRate1: ScheduledFuture<*>? = null var scheduleAtFixedRate1: ScheduledFuture<*>? = null
val okHttpClient: OkHttpClient private val okHttpClient: OkHttpClient
val gson: Gson val gson: Gson
val mmkv = MMKV.mmkvWithID("InterProcessKV", MMKV.MULTI_PROCESS_MODE) val mmkv = MMKV.mmkvWithID("InterProcessKV", MMKV.MULTI_PROCESS_MODE)
...@@ -47,13 +45,13 @@ object AuthManager { ...@@ -47,13 +45,13 @@ object AuthManager {
init { init {
okHttpClient = OkHttpClient().newBuilder() okHttpClient = OkHttpClient().newBuilder()
.readTimeout(60, TimeUnit.SECONDS)//设置读取超时时间 .readTimeout(60, TimeUnit.SECONDS)//设置读取超时时间
.writeTimeout(60, TimeUnit.SECONDS)//设置写的超时时间 .writeTimeout(60, TimeUnit.SECONDS)//设置写的超时时间
.connectTimeout(60, TimeUnit.SECONDS)//设置连接超时时间 .connectTimeout(60, TimeUnit.SECONDS)//设置连接超时时间
//https支持 //https支持
.hostnameVerifier { hostname, session -> true } .hostnameVerifier { hostname, session -> true }
.sslSocketFactory(initSSLSocketFactory(), initTrustManager()) .sslSocketFactory(initSSLSocketFactory(), initTrustManager())
.build() .build()
gson = Gson() gson = Gson()
} }
...@@ -103,7 +101,7 @@ object AuthManager { ...@@ -103,7 +101,7 @@ object AuthManager {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val gameId: Int = gameId?.toInt() ?: throw AuthException("游戏不存在") val gameId: Int = gameId?.toInt() ?: throw AuthException("游戏不存在")
val lineConfigResult = val lineConfigResult =
postSync<LineConfig>("/api/acc/line", authToken, LineConfigReq(gameId, area)) postSync<LineConfig>("/api/acc/line", authToken, LineConfigReq(gameId, area))
if (lineConfigResult.isSuccessful()) { if (lineConfigResult.isSuccessful()) {
val lineConfig = lineConfigResult.unwrapData() val lineConfig = lineConfigResult.unwrapData()
profile.host = lineConfig.host profile.host = lineConfig.host
...@@ -126,15 +124,15 @@ object AuthManager { ...@@ -126,15 +124,15 @@ object AuthManager {
if (data.state != BaseService.State.Connected) { if (data.state != BaseService.State.Connected) {
return return
} }
NetworkAdapter.initNetworks(Core.deviceStorage) NetworkAdapter.initNetworks(Core.app)
scheduleAtFixedRate?.cancel(false) scheduleAtFixedRate?.cancel(false)
var failedCount: Int = 0 var failedCount: Int = 0
scheduleAtFixedRate = executor.scheduleAtFixedRate({ scheduleAtFixedRate = executor.scheduleAtFixedRate({
if (data.state == BaseService.State.Connected) { if (data.state == BaseService.State.Connected) {
data.proxy?.let { proxyInstance -> data.proxy?.let { proxyInstance ->
val refreshTokenResult = postSync<RefreshTokenRes>( val refreshTokenResult = postSync<RefreshTokenRes>(
"/api/acc/line/refresh", authToken, "/api/acc/line/refresh", authToken,
RefreshTokenReq(proxyInstance.profile.token ?: "") RefreshTokenReq(proxyInstance.profile.token ?: "")
) )
Timber.d("refreshTokenResult: $refreshTokenResult") Timber.d("refreshTokenResult: $refreshTokenResult")
if (refreshTokenResult.isSuccessful()) { if (refreshTokenResult.isSuccessful()) {
...@@ -161,26 +159,28 @@ object AuthManager { ...@@ -161,26 +159,28 @@ object AuthManager {
}, 1, 1, TimeUnit.MINUTES) }, 1, 1, TimeUnit.MINUTES)
scheduleAtFixedRate1?.cancel(false) scheduleAtFixedRate1?.cancel(false)
scheduleAtFixedRate1 = executor.scheduleAtFixedRate( scheduleAtFixedRate1 = executor.scheduleAtFixedRate(
{ {
Timber.d("testLatency") Timber.d("testLatency")
GlobalScope.launch { GlobalScope.launch {
testLatency() testLatency()
if (wifiLatencyList.size == 5) { if (wifiLatencyList.size == 5) {
val wifiavg = wifiLatencyList.average().toInt() val wifiavg = wifiLatencyList.average().toInt()
val celavg = cellularLatencyList.average().toInt() val celavg = cellularLatencyList.average().toInt()
if (wifiavg > celavg && wifiavg > 200 && celavg != -1) { if (wifiavg > celavg && wifiavg > 200 && celavg != -1) {
NetworkAdapter.useCellular(Core.deviceStorage) NetworkAdapter.useCellular(Core.deviceStorage)
} else if (celavg > wifiavg && wifiavg != -1) { Timber.d("switch to cellular")
NetworkAdapter.useWifi(Core.deviceStorage) } else if (celavg > wifiavg && wifiavg != -1) {
NetworkAdapter.useWifi(Core.deviceStorage)
Timber.d("switch to wifi")
}
wifiLatencyList.clear()
cellularLatencyList.clear()
} }
wifiLatencyList.clear()
cellularLatencyList.clear()
} }
} },
}, 1,
20, 1,
20, TimeUnit.SECONDS
TimeUnit.SECONDS
) )
} }
...@@ -189,18 +189,18 @@ object AuthManager { ...@@ -189,18 +189,18 @@ object AuthManager {
private suspend fun testLatency() { private suspend fun testLatency() {
val networkAutoSwitch = val networkAutoSwitch =
isSmartAccOpen // 根据用户设置测试延迟 ,过高时切换 connection.bindNetwork(NetworkMode.CELLULAR.code) isSmartAccOpen // 根据用户设置测试延迟 ,过高时切换 connection.bindNetwork(NetworkMode.CELLULAR.code)
if (networkAutoSwitch) { if (networkAutoSwitch) {
val wifiLatency: Int = doTestLatency( val wifiLatency: Int = doTestLatency(
"114.114.114.114", "114.114.114.114",
53, 53,
NetworkAdapter.wifiNetwork NetworkAdapter.wifiNetwork
) )
wifiLatencyList.add(wifiLatency) wifiLatencyList.add(wifiLatency)
val cellularLatency: Int = doTestLatency( val cellularLatency: Int = doTestLatency(
"114.114.114.114", "114.114.114.114",
53, 53,
NetworkAdapter.cellularNetwork NetworkAdapter.cellularNetwork
) )
cellularLatencyList.add(cellularLatency) cellularLatencyList.add(cellularLatency)
Timber.d("wifi latency: $wifiLatency, cellular latency: $cellularLatency") Timber.d("wifi latency: $wifiLatency, cellular latency: $cellularLatency")
...@@ -208,10 +208,10 @@ object AuthManager { ...@@ -208,10 +208,10 @@ object AuthManager {
} }
private suspend fun doTestLatency( private suspend fun doTestLatency(
pingHost: String, pingHost: String,
pingPort: Int, pingPort: Int,
network: Network?, network: Network?,
systemNetwork: Boolean = false systemNetwork: Boolean = false
): Int { ): Int {
return withTimeoutOrNull(DataStore.pingTimeoutMillis.toLong()) { return withTimeoutOrNull(DataStore.pingTimeoutMillis.toLong()) {
try { try {
...@@ -228,8 +228,8 @@ object AuthManager { ...@@ -228,8 +228,8 @@ object AuthManager {
} }
val start = System.currentTimeMillis() val start = System.currentTimeMillis()
socketAddress.connect( socketAddress.connect(
InetSocketAddress(pingHost, pingPort), InetSocketAddress(pingHost, pingPort),
DataStore.pingTimeoutMillis DataStore.pingTimeoutMillis
) )
(System.currentTimeMillis() - start).toInt() (System.currentTimeMillis() - start).toInt()
} catch (_: Exception) { } catch (_: Exception) {
...@@ -240,17 +240,17 @@ object AuthManager { ...@@ -240,17 +240,17 @@ object AuthManager {
var loginAuthToken: String = "1" var loginAuthToken: String = "1"
val jsonType get() = "application/json; charset=utf-8".toMediaTypeOrNull() private val jsonType get() = "application/json; charset=utf-8".toMediaTypeOrNull()
inline fun <reified T> postSync( private inline fun <reified T> postSync(
url: String, url: String,
token: String?, token: String?,
params: Any params: Any
): ApiResult<T> { ): ApiResult<T> {
val body: RequestBody = gson.toJson(params).toString().toRequestBody(jsonType) val body: RequestBody = gson.toJson(params).toString().toRequestBody(jsonType)
val request = Request.Builder() val request = Request.Builder()
.url(if (url.startsWith("http")) url else HttpConfig.baseUrl + url) .url(if (url.startsWith("http")) url else HttpConfig.baseUrl + url)
.post(body) .post(body)
token?.let { token?.let {
request.addHeader("Authorization", it) request.addHeader("Authorization", it)
} }
...@@ -274,15 +274,69 @@ object AuthManager { ...@@ -274,15 +274,69 @@ object AuthManager {
sslContext = SSLContext.getInstance("SSL") sslContext = SSLContext.getInstance("SSL")
val xTrustArray = arrayOf(initTrustManager()) val xTrustArray = arrayOf(initTrustManager())
sslContext.init( sslContext.init(
null, null,
xTrustArray, SecureRandom() xTrustArray, SecureRandom()
) )
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
return sslContext!!.socketFactory return AutoSwitchNetworkSocketFactory(sslContext!!.socketFactory)
}
private class AutoSwitchNetworkSocketFactory(private val delegate: SSLSocketFactory) : SSLSocketFactory() {
override fun createSocket(s: Socket?, host: String?, port: Int, autoClose: Boolean): Socket {
val bindNetwork = NetworkAdapter.bindNetwork
val createSocket = delegate.createSocket(s, host, port, autoClose)
bindNetwork?.bindSocket(createSocket)
return createSocket
}
override fun createSocket(host: String?, port: Int): Socket {
val bindNetwork = NetworkAdapter.bindNetwork
return if (bindNetwork != null) {
bindNetwork.socketFactory.createSocket(host, port)
} else {
delegate.createSocket(host, port)
}
}
override fun createSocket(host: String?, port: Int, localHost: InetAddress?, localPort: Int): Socket {
val bindNetwork = NetworkAdapter.bindNetwork
return if (bindNetwork != null) {
bindNetwork.socketFactory.createSocket(host, port, localHost, localPort)
} else {
delegate.createSocket(host, port, localHost, localPort)
}
}
override fun createSocket(host: InetAddress?, port: Int): Socket {
val bindNetwork = NetworkAdapter.bindNetwork
return if (bindNetwork != null) {
bindNetwork.socketFactory.createSocket(host, port)
} else {
delegate.createSocket(host, port)
}
}
override fun createSocket(address: InetAddress?, port: Int, localAddress: InetAddress?, localPort: Int): Socket {
val bindNetwork = NetworkAdapter.bindNetwork
return if (bindNetwork != null) {
bindNetwork.socketFactory.createSocket(address, port, localAddress, localPort)
} else {
delegate.createSocket(address, port, localAddress, localPort)
}
}
override fun getDefaultCipherSuites(): Array<String> {
return delegate.defaultCipherSuites
}
override fun getSupportedCipherSuites(): Array<String> {
return delegate.supportedCipherSuites
}
} }
private fun initTrustManager(): X509TrustManager { private fun initTrustManager(): X509TrustManager {
......
...@@ -23,6 +23,7 @@ package com.github.shadowsocks.bg ...@@ -23,6 +23,7 @@ package com.github.shadowsocks.bg
import android.net.LocalSocket import android.net.LocalSocket
import android.os.SystemClock import android.os.SystemClock
import com.ccnet.acc.AccVpnService import com.ccnet.acc.AccVpnService
import com.ccnet.acc.NetworkAdapter
import com.ccnet.acc.TestLatencyCallback import com.ccnet.acc.TestLatencyCallback
import com.github.shadowsocks.aidl.TrafficStats import com.github.shadowsocks.aidl.TrafficStats
import com.github.shadowsocks.database.ProfileManager import com.github.shadowsocks.database.ProfileManager
...@@ -72,6 +73,7 @@ class TrafficMonitor(statFile: File?) { ...@@ -72,6 +73,7 @@ class TrafficMonitor(statFile: File?) {
override fun run() { override fun run() {
Timber.d("TrafficMonitor-NativePing prepare test ${DataStore.pingAccHost}:${DataStore.pingAccPort}") Timber.d("TrafficMonitor-NativePing prepare test ${DataStore.pingAccHost}:${DataStore.pingAccPort}")
var bindNetwork = NetworkAdapter.bindNetwork
while (running) { while (running) {
val resultCode = AccVpnService.instance.testLatency( val resultCode = AccVpnService.instance.testLatency(
DataStore.pingProxyServer, DataStore.pingProxyServer,
...@@ -80,10 +82,15 @@ class TrafficMonitor(statFile: File?) { ...@@ -80,10 +82,15 @@ class TrafficMonitor(statFile: File?) {
DataStore.pingIntervalSec, DataStore.pingIntervalSec,
DataStore.pingTimeoutMillis, DataStore.pingTimeoutMillis,
object : TestLatencyCallback { object : TestLatencyCallback {
override fun onLatency(latency: Int) { override fun onLatency(latency: Int): Boolean {
Timber.d("TrafficMonitor-NativeTcpPing test ${current.latency}") Timber.d("TrafficMonitor-NativeTcpPing test ${current.latency}")
current.latency = latency current.latency = latency
dirty = true dirty = true
val cont = bindNetwork == NetworkAdapter.bindNetwork
if (!cont) {
bindNetwork = NetworkAdapter.bindNetwork
}
return cont
} }
} }
) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment