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