mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2025-12-06 06:52:01 +01:00
Gracefully handle a disconnection from an idle secondary DC
(don't reconnect)
This commit is contained in:
parent
e8a98a5799
commit
934895a81c
9
FAQ.md
9
FAQ.md
|
|
@ -1,6 +1,6 @@
|
|||
## FAQ
|
||||
|
||||
#### 1. How to remove the Console logs ?
|
||||
#### 1. How to remove the Console logs?
|
||||
|
||||
Writing the library logs to the Console is the default behavior of the `WTelegram.Helpers.Log` delegate.
|
||||
You can change the delegate with the `+=` operator to **also** write them somewhere else, or with the `=` operator to prevent them from being printed to screen and instead write them somewhere (file, logger, ...).
|
||||
|
|
@ -14,7 +14,7 @@ The WTelegram.session file contains the authentication keys negociated for the c
|
|||
|
||||
You could switch the current user via an `Auth_Logout` followed by a `LoginUserIfNeeded` but that would require the user to sign in with a verification_code each time.
|
||||
|
||||
Instead, if you want to deal with multiple users, the recommended solution is to have a different session file for each user. This can be done by having your Config callback reply with a different filename (or folder) for "**session_pathname**" for each user.
|
||||
Instead, if you want to deal with multiple users from the same machine, the recommended solution is to have a different session file for each user. This can be done by having your Config callback reply with a different filename (or folder) for "**session_pathname**" for each user.
|
||||
This way, you can keep separate session files (each with their authentication keys) for each user.
|
||||
|
||||
If you need to manage these user accounts in parallel, you can create multiple instances of WTelegram.Client, and give them a Config callback that will select a different session file.
|
||||
|
|
@ -97,14 +97,13 @@ Here are some key points:
|
|||
|
||||
*(the above section is derived from [gotd SUPPORT.md](https://github.com/gotd/td/blob/main/.github/SUPPORT.md))*
|
||||
|
||||
|
||||
#### 8. I can't import phone numbers. I get error PHONE_NUMBER_BANNED or FLOOD_WAIT_84200
|
||||
#### 8. I can't import phone numbers. I get error PHONE_NUMBER_BANNED or FLOOD_WAIT_8xxxx
|
||||
|
||||
You can get these kind of problems if you abuse Telegram [Terms of Service](https://telegram.org/tos) or make excessive requests.
|
||||
|
||||
You can try to wait more between the requests, wait for a day or two to see if the requests become possible again.
|
||||
|
||||
If you think your phone number was banned for a bad reason, you may try to contact [recover@telegram.org](mailto:recover@telegram.org), explaining what you were doing.
|
||||
If you think your phone number was banned for a wrong reason, you may try to contact [recover@telegram.org](mailto:recover@telegram.org), explaining what you were doing.
|
||||
|
||||
In any case, WTelegramClient is not responsible for the bad usage of the library and we are not affiliated to Telegram teams, so there is nothing we can do.
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ There are other configuration items that are queried to your method but returnin
|
|||
Those shown above are the only ones that have no default values and <u>should be provided</u> by your method.
|
||||
Returning `null` for verification_code or password will show a prompt for console apps, or an error otherwise.
|
||||
|
||||
Another simpler approach is to pass `Environment.GetEnvironmentVariable` as the config callback and define the configuration items as environment variables.
|
||||
Another simple approach is to pass `Environment.GetEnvironmentVariable` as the config callback and define the configuration items as environment variables.
|
||||
Undefined variables get the default `null` behavior.
|
||||
|
||||
Finally, if you want to redirect the library logs to your logger instead of the Console, you can install a delegate in the `WTelegram.Helpers.Log` static property.
|
||||
|
|
@ -101,7 +101,7 @@ Console.WriteLine($"Sending a message in chat {chatId}: {target.Title}");
|
|||
await client.SendMessageAsync(target, "Hello, World");
|
||||
```
|
||||
|
||||
You can find more useful code snippets in [EXAMPLES.md](https://github.com/wiz0u/WTelegramClient/blob/master/EXAMPLES.md) and in the [Examples subdirectory](https://github.com/wiz0u/WTelegramClient/tree/master/Examples).
|
||||
➡️ You can find more useful code snippets in [EXAMPLES.md](https://github.com/wiz0u/WTelegramClient/blob/master/EXAMPLES.md) and in the [Examples subdirectory](https://github.com/wiz0u/WTelegramClient/tree/master/Examples).
|
||||
|
||||
# Terminology in Telegram Client API
|
||||
|
||||
|
|
@ -142,6 +142,6 @@ Secret chats (end-to-end encryption, PFS) and connection to CDN DCs have not bee
|
|||
Please don't use this library for Spam or Scam. Respect Telegram [Terms of Service](https://telegram.org/tos) or you might get banned from Telegram servers.
|
||||
|
||||
Developers feedbacks are welcome in the Telegram support group [@WTelegramClient](https://t.me/WTelegramClient)
|
||||
You can also check our [Frequently Asked Questions](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md) for more help and troubleshooting guide.
|
||||
You can also check our [📖 Frequently Asked Questions](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md) for more help and troubleshooting guide.
|
||||
|
||||
If you like this library, please [consider a donation](http://wizou.fr/donate.html). ❤ This will help the project keep going.
|
||||
If you like this library, please [consider a donation](http://wizou.fr/donate.html).❤ This will help the project keep going.
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ namespace WTelegram
|
|||
private CancellationTokenSource _cts;
|
||||
private int _reactorReconnects = 0;
|
||||
private const int FilePartSize = 512 * 1024;
|
||||
private const string ConnectionShutDown = "Could not read payload length : Connection shut down";
|
||||
private readonly SemaphoreSlim _parallelTransfers = new(10); // max parallel part uploads/downloads
|
||||
#if MTPROTO1
|
||||
private readonly SHA1 _sha1 = SHA1.Create();
|
||||
|
|
@ -391,7 +392,7 @@ namespace WTelegram
|
|||
try
|
||||
{
|
||||
if (await FullReadAsync(stream, data, 4, cts.Token) != 4)
|
||||
throw new ApplicationException("Could not read payload length : Connection shut down");
|
||||
throw new ApplicationException(ConnectionShutDown);
|
||||
int payloadLen = BinaryPrimitives.ReadInt32LittleEndian(data);
|
||||
if (payloadLen > data.Length)
|
||||
data = new byte[payloadLen];
|
||||
|
|
@ -405,17 +406,20 @@ namespace WTelegram
|
|||
catch (Exception ex) // an exception in RecvAsync is always fatal
|
||||
{
|
||||
if (cts.IsCancellationRequested) return;
|
||||
Helpers.Log(5, $"An exception occured in the reactor: {ex}");
|
||||
Helpers.Log(5, $"{_dcSession.DcID}>An exception occured in the reactor: {ex}");
|
||||
var oldSemaphore = _sendSemaphore;
|
||||
await oldSemaphore.WaitAsync(cts.Token); // prevent any sending while we reconnect
|
||||
var reactorError = new ReactorError { Exception = ex };
|
||||
try
|
||||
{
|
||||
lock (_msgsToAck) _msgsToAck.Clear();
|
||||
Reset(false, false);
|
||||
_reactorReconnects = (_reactorReconnects + 1) % MaxAutoReconnects;
|
||||
if (!IsMainDC && _pendingRequests.Count <= 1 && ex is ApplicationException { Message: ConnectionShutDown } or IOException { InnerException: SocketException })
|
||||
if (_pendingRequests.Values.FirstOrDefault() is var (type, tcs) && (type is null || type == typeof(Pong)))
|
||||
_reactorReconnects = 0;
|
||||
if (_reactorReconnects != 0)
|
||||
{
|
||||
lock (_msgsToAck) _msgsToAck.Clear();
|
||||
Reset(false, false);
|
||||
await Task.Delay(5000);
|
||||
await ConnectAsync(); // start a new reactor after 5 secs
|
||||
lock (_pendingRequests) // retry all pending requests
|
||||
|
|
@ -450,7 +454,6 @@ namespace WTelegram
|
|||
{
|
||||
oldSemaphore.Release();
|
||||
}
|
||||
cts.Cancel(); // always stop the reactor
|
||||
}
|
||||
if (obj != null)
|
||||
await HandleMessageAsync(obj);
|
||||
|
|
@ -584,8 +587,8 @@ namespace WTelegram
|
|||
writer.Write(0L); // int64 auth_key_id = 0 (Unencrypted)
|
||||
writer.Write(msgId); // int64 message_id
|
||||
writer.Write(0); // int32 message_data_length (to be patched)
|
||||
writer.WriteTLObject(msg); // bytes message_data
|
||||
Helpers.Log(1, $"{_dcSession.DcID}>Sending {msg.GetType().Name.TrimEnd('_')}...");
|
||||
writer.WriteTLObject(msg); // bytes message_data
|
||||
BinaryPrimitives.WriteInt32LittleEndian(memStream.GetBuffer().AsSpan(20), (int)memStream.Length - 24); // patch message_data_length
|
||||
}
|
||||
else
|
||||
|
|
@ -603,11 +606,11 @@ namespace WTelegram
|
|||
clearWriter.Write(msgId); // int64 message_id
|
||||
clearWriter.Write(seqno); // int32 msg_seqno
|
||||
clearWriter.Write(0); // int32 message_data_length (to be patched)
|
||||
clearWriter.WriteTLObject(msg); // bytes message_data
|
||||
if ((seqno & 1) != 0)
|
||||
Helpers.Log(1, $"{_dcSession.DcID}>Sending {msg.GetType().Name.TrimEnd('_'),-40} #{(short)msgId.GetHashCode():X4}");
|
||||
else
|
||||
Helpers.Log(1, $"{_dcSession.DcID}>Sending {msg.GetType().Name.TrimEnd('_'),-40} {MsgIdToStamp(msgId):u} (svc)");
|
||||
clearWriter.WriteTLObject(msg); // bytes message_data
|
||||
int clearLength = (int)clearStream.Length - prepend; // length before padding (= 32 + message_data_length)
|
||||
int padding = (0x7FFFFFF0 - clearLength) % 16;
|
||||
#if !MTPROTO1
|
||||
|
|
|
|||
|
|
@ -178,9 +178,9 @@ namespace TL
|
|||
writer.Write(0); // patched below
|
||||
writer.WriteTLObject(msg.body);
|
||||
if ((msg.seqno & 1) != 0)
|
||||
WTelegram.Helpers.Log(1, $" Sending → {msg.body.GetType().Name.TrimEnd('_'),-40} #{(short)msg.msg_id.GetHashCode():X4}");
|
||||
WTelegram.Helpers.Log(1, $" → {msg.body.GetType().Name.TrimEnd('_'),-38} #{(short)msg.msg_id.GetHashCode():X4}");
|
||||
else
|
||||
WTelegram.Helpers.Log(1, $" Sending → {msg.body.GetType().Name.TrimEnd('_'),-40}");
|
||||
WTelegram.Helpers.Log(1, $" → {msg.body.GetType().Name.TrimEnd('_'),-38}");
|
||||
writer.BaseStream.Position = patchPos;
|
||||
writer.Write((int)(writer.BaseStream.Length - patchPos - 4)); // patch bytes field
|
||||
writer.Seek(0, SeekOrigin.End);
|
||||
|
|
|
|||
Loading…
Reference in a new issue