fix(app): ping the relay, retry stuck messages, drop duplicates
A message sent into a dead socket ended up as failed — attachments even stayed on "sending" forever — and only the user could send it again by hand. Mobile NAT drops idle TCP silently, so neither side knew. - pingInterval on the WebSocket, so the client notices a dead link itself - outbox: after every reconnect, stuck messages are re-sent (batch of 30, up to a day old); permanent errors are not retried - sendAttachment gained the try/catch it was missing, otherwise the attachment never reached the outbox - de-duplicate by message id: a retry re-sends the SAME message, which would otherwise show up twice on the other side
This commit is contained in:
@@ -21,6 +21,15 @@ import 'package:socks5_proxy/socks_client.dart';
|
||||
import 'package:web_socket_channel/io.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
|
||||
/// Jak často posílat WS ping a jak dlouho čekat na pong.
|
||||
///
|
||||
/// Bez pingu se mrtvé spojení tváří jako živé: mobilní NAT zahodí nečinné TCP
|
||||
/// tiše, appka dál hlásí „připojeno" a píše do prázdna — zprávy pak odejdou až
|
||||
/// po restartu appky, všechny naráz. `dart:io` při nastaveném intervalu ping
|
||||
/// posílá a když pong nedorazí včas, spojení zavře → [RelayClient] se
|
||||
/// reconnectne sám. Relay pinguje protisměrně po 30 s (ws.rs PING_INTERVAL).
|
||||
const kWsPingInterval = Duration(seconds: 30);
|
||||
|
||||
/// Abstrakce nad tím, jak klient otevírá spojení k relayi.
|
||||
abstract class RelayTransport {
|
||||
/// Sdílený HTTP klient pro REST (registrace, prekey bundle, přílohy…).
|
||||
@@ -41,7 +50,8 @@ class DirectTransport implements RelayTransport {
|
||||
http.Client httpClient() => _client ??= http.Client();
|
||||
|
||||
@override
|
||||
WebSocketChannel connectWs(Uri url) => WebSocketChannel.connect(url);
|
||||
WebSocketChannel connectWs(Uri url) =>
|
||||
IOWebSocketChannel.connect(url, pingInterval: kWsPingInterval);
|
||||
|
||||
@override
|
||||
void close() {
|
||||
@@ -84,7 +94,7 @@ class TorTransport implements RelayTransport {
|
||||
@override
|
||||
WebSocketChannel connectWs(Uri url) =>
|
||||
IOWebSocketChannel.connect(_withExplicitPort(url),
|
||||
customClient: _sharedHttpClient());
|
||||
customClient: _sharedHttpClient(), pingInterval: kWsPingInterval);
|
||||
|
||||
/// `Uri` pro `ws`/`wss` nezná výchozí port → `url.port` vrací 0 a SOCKS
|
||||
/// CONNECT by cílil na port 0 (serverError). Doplníme ho podle schématu
|
||||
|
||||
Reference in New Issue
Block a user