Add Keep-Alive system (will also send pending acks)

This commit is contained in:
Wizou 2021-09-17 03:12:23 +02:00
parent b17349bd75
commit 184a133dce

View file

@ -121,7 +121,7 @@ namespace WTelegram
_networkStream = _tcpClient.GetStream(); _networkStream = _tcpClient.GetStream();
_frame_seqTx = _frame_seqRx = 0; _frame_seqTx = _frame_seqRx = 0;
_cts = new(); _cts = new();
_reactorTask = Reactor(_networkStream, _cts.Token); _reactorTask = Reactor(_networkStream, _cts);
_sendSemaphore.Release(); _sendSemaphore.Release();
if (_session.AuthKey == null) if (_session.AuthKey == null)
@ -164,22 +164,33 @@ namespace WTelegram
} }
} }
private async Task Reactor(NetworkStream stream, CancellationToken ct) private async Task KeepAlive(CancellationToken ct)
{ {
int reconnects = 0; int ping_id = _random.Next();
while (!ct.IsCancellationRequested) while (!ct.IsCancellationRequested)
{ {
ITLObject obj; await Task.Delay(60000, ct);
await PingDelayDisconnect(ping_id++, 75);
}
}
private async Task Reactor(NetworkStream stream, CancellationTokenSource cts)
{
int reconnects = 0;
var keepAliveTask = KeepAlive(cts.Token);
while (!cts.IsCancellationRequested)
{
ITLObject obj = null;
try try
{ {
obj = await RecvAsync(stream, ct); obj = await RecvAsync(stream, cts.Token);
} }
catch (Exception ex) // an exception in RecvAsync is always fatal catch (Exception ex) // an exception in RecvAsync is always fatal
{ {
if (ct.IsCancellationRequested) return; if (cts.IsCancellationRequested) return;
Helpers.Log(5, $"An exception occured in the reactor: {ex}"); Helpers.Log(5, $"An exception occured in the reactor: {ex}");
var oldSemaphore = _sendSemaphore; var oldSemaphore = _sendSemaphore;
await oldSemaphore.WaitAsync(ct); // prevent any sending while we reconnect await oldSemaphore.WaitAsync(cts.Token); // prevent any sending while we reconnect
try try
{ {
lock (_pendingRequests) // abort all pending requests lock (_pendingRequests) // abort all pending requests
@ -202,7 +213,7 @@ namespace WTelegram
{ {
oldSemaphore.Release(); oldSemaphore.Release();
} }
return; // always stop the reactor cts.Cancel(); // always stop the reactor
} }
if (obj != null) if (obj != null)
await HandleMessageAsync(obj); await HandleMessageAsync(obj);