Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a24a6f6c0 | ||
|
|
b847320360 | ||
|
|
203e5f6ed5 |
@@ -11,8 +11,8 @@ android {
|
|||||||
applicationId = "ru.ua1zbe.svxremote"
|
applicationId = "ru.ua1zbe.svxremote"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 15
|
versionCode = 16
|
||||||
versionName = "1.0.13"
|
versionName = "1.0.14"
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|||||||
@@ -85,6 +85,15 @@ class ReflectorClient(
|
|||||||
@Volatile
|
@Volatile
|
||||||
private var fatal = false
|
private var fatal = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Была ли хотя бы одна успешная сессия за текущее подключение.
|
||||||
|
* Если да — креды уже проверены, поэтому ошибки на рукопожатии считаем
|
||||||
|
* временными (сервер мог ещё держать старую сессию после обрыва) и
|
||||||
|
* продолжаем автопереподключение вместо показа «ошибки авторизации».
|
||||||
|
*/
|
||||||
|
@Volatile
|
||||||
|
private var everReady = false
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var tcpSocket: Socket? = null
|
private var tcpSocket: Socket? = null
|
||||||
private var udpSocket: DatagramSocket? = null
|
private var udpSocket: DatagramSocket? = null
|
||||||
@@ -107,6 +116,7 @@ class ReflectorClient(
|
|||||||
this.settings = settings
|
this.settings = settings
|
||||||
manualDisconnect.set(false)
|
manualDisconnect.set(false)
|
||||||
fatal = false
|
fatal = false
|
||||||
|
everReady = false
|
||||||
if (running.get()) {
|
if (running.get()) {
|
||||||
// Перезапуск с новыми настройками (например, смена профиля)
|
// Перезапуск с новыми настройками (например, смена профиля)
|
||||||
running.set(false)
|
running.set(false)
|
||||||
@@ -254,7 +264,10 @@ class ReflectorClient(
|
|||||||
callbacks.onState(STATE_TCP_CONNECTED)
|
callbacks.onState(STATE_TCP_CONNECTED)
|
||||||
startTcpSenderThread(socket, s)
|
startTcpSenderThread(socket, s)
|
||||||
runTcpLoop(socket, s)
|
runTcpLoop(socket, s)
|
||||||
true
|
// runTcpLoop завершилась: если всё ещё должны работать — значит
|
||||||
|
// соединение разорвано/отклонено, вернём false, чтобы reconnectLoop
|
||||||
|
// выдержал RECONNECT_DELAY_MS и не бомбил сервер переподключениями.
|
||||||
|
!running.get()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
try {
|
try {
|
||||||
socket.close()
|
socket.close()
|
||||||
@@ -399,6 +412,7 @@ class ReflectorClient(
|
|||||||
serverCodecs = info.codecs
|
serverCodecs = info.codecs
|
||||||
callbacks.onServerInfo(info)
|
callbacks.onServerInfo(info)
|
||||||
state = STATE_READY
|
state = STATE_READY
|
||||||
|
everReady = true
|
||||||
callbacks.onState(STATE_READY)
|
callbacks.onState(STATE_READY)
|
||||||
// Сначала сообщаем о себе (версия ПО для дашборда), затем
|
// Сначала сообщаем о себе (версия ПО для дашборда), затем
|
||||||
// выбираем TG для передачи и подписываемся на прослушивание
|
// выбираем TG для передачи и подписываемся на прослушивание
|
||||||
@@ -441,9 +455,17 @@ class ReflectorClient(
|
|||||||
|
|
||||||
ReflectorProtocol.MSG_ERROR -> {
|
ReflectorProtocol.MSG_ERROR -> {
|
||||||
val err = MsgParser.errorMessage(msg.fields)
|
val err = MsgParser.errorMessage(msg.fields)
|
||||||
Log.w(TAG, "MSG_ERROR: $err")
|
Log.w(TAG, "MSG_ERROR: $err (state=$state, everReady=$everReady)")
|
||||||
if (state < STATE_READY) {
|
if (state < STATE_READY) {
|
||||||
stopFatal(err.ifEmpty { "Access denied" })
|
if (everReady) {
|
||||||
|
// Креды проверены ранее: ошибка на рукопожатии почти
|
||||||
|
// всегда временная (сервер ещё держит старую сессию
|
||||||
|
// после короткого обрыва) — переподключаемся заново.
|
||||||
|
callbacks.onState(STATE_ERROR, err.ifEmpty { "Переподключение" })
|
||||||
|
abortSockets()
|
||||||
|
} else {
|
||||||
|
stopFatal(err.ifEmpty { "Access denied" })
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
callbacks.onError(err)
|
callbacks.onError(err)
|
||||||
@@ -452,7 +474,13 @@ class ReflectorClient(
|
|||||||
else -> Unit // неизвестные сообщения игнорируются
|
else -> Unit // неизвестные сообщения игнорируются
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
stopFatal("Ошибка протокола: ${e.message}")
|
if (everReady) {
|
||||||
|
// Сбой после успешного подключения — не фатально, переподключаемся.
|
||||||
|
callbacks.onState(STATE_ERROR, "Ошибка протокола: ${e.message}")
|
||||||
|
abortSockets()
|
||||||
|
} else {
|
||||||
|
stopFatal("Ошибка протокола: ${e.message}")
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -478,7 +506,12 @@ class ReflectorClient(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun protocolError(detail: String): Boolean {
|
private fun protocolError(detail: String): Boolean {
|
||||||
stopFatal(detail)
|
if (everReady) {
|
||||||
|
callbacks.onState(STATE_ERROR, detail)
|
||||||
|
abortSockets()
|
||||||
|
} else {
|
||||||
|
stopFatal(detail)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user