sochix / TLSharp

Telegram client library implemented in C#
1.01k stars 380 forks source link

GetUserDialogsAsync stuck #944

Closed wcypierre closed 4 years ago

wcypierre commented 4 years ago

I was testing the send message to group functionality based on the code in the test case and the code gets stuck at GetUserDialogsAsync, there is no exception thrown as I tried to catch it.

Any hints on what can I try?

Code is as below:

using (var teleClient = new TelegramClient(apiId, apiHash)) { try { await teleClient.ConnectAsync();

    await teleClient.SendPingAsync();
    var dialogs = await teleClient.GetUserDialogsAsync() as TLDialogs;
    var chat = dialogs.Chats.OfType<TLChannel>().FirstOrDefault(x => x.Title == groupName);
    await teleClient.SendMessageAsync(new TLInputPeerChannel() { ChannelId = chat.Id, AccessHash = chat.AccessHash.Value }, "Testing");
}
catch (FloodException fe)
{
    throw fe;
}
catch (Exception e)
{
    throw e;
}

}

wcypierre commented 4 years ago

If I close it and run again, the program stucks at ConnectAsync instead until I think the timeout reaches and I can connect again

wcypierre commented 4 years ago

Did some digging on the source code instead, and turns out that calling GetUserDialogsAsync fails (ConnectAsync works though) when the ip is 2001:0b28:f23d:f001:0000:0000:0000:000a.

Tried forcing it to ipv4 (currently using 91.108.56.180) and it works.

Steps done:

  1. Deleted session.dat
  2. new TelegramClient with DataCenterIPVersion.OnlyIPv4

I'd probably suggest exposing Session.Datacenter.Address, Port and DataCenterId via 3 getter in Session.cs and TelegramClient.cs, easier for basic troubleshooting such as connectivity test.

wcypierre commented 4 years ago

But then, likely that each DC supports a different set of functionality that and so that is what causing the issue.

Seems to relate to this issue https://github.com/sochix/TLSharp/issues/935 but need to check more on it.

knocte commented 4 years ago

Seems to relate to this issue #935 but need to check more on it.

Hey @wcypierre thanks for investigating. Do you mean that you were not using a version of TLSharp with a fix for #935?

wcypierre commented 4 years ago

@knocte what is the related PR for it? I was using version 0.1.0.555 from nuget (targeting .net 4.6), and subsequently using master (commit bca8bc56) and both have the same issues until I changed the datacenter

wcypierre commented 4 years ago

if it is this PR https://github.com/sochix/TLSharp/pull/938 then it is still breaking for my case

knocte commented 4 years ago

Yes that's the PR. I see :(

wcypierre commented 4 years ago

Do you need me to do any further checking (and what should I check)? I can do it but probably later in the day because I'm still using it atm (don't want it to break out of the sudden)

knocte commented 4 years ago

I don't know, maybe compare the DC properties of the one that fails with the one that works?

wcypierre commented 4 years ago

I reckon that it is just the ip that is different, but will dig further later tonight

wcypierre commented 4 years ago

And this ip 2001:b28:f23f:f005::a seems not to be returning the result for GetUserDialogsAsync but the program is expecting something and there is no timeout and so it hangs (I thought there was an exception but there's none).

Need your expertise in this matter on whether are we able to query other DC's properties other than the mediaonly, tcponly, ip, port, cdn

Flow:

  1. AuthUser test case
  2. SendMessageToChannelTest test case 2.1 client.GetUserDialogsAsync() 2.2 TelegramClient.cs -> RequestWithDcMigration -> sender.Receive 2.3 MtProtoSender.cs -> transport.Receive -> await stream.ReadAsync (stuck at the nth loop)

Working IP: 91.108.56.180

wcypierre commented 4 years ago

okay, seems like if the server doesn't respond then setting a timeout doesn't work either (not the solution but letting it hang there can make things hard to troubleshoot)

https://stackoverflow.com/questions/6958255/what-are-some-reasons-networkstream-read-would-hang-block/6958290#6958290

Are we able to query the DC's supported layer?

wcypierre commented 4 years ago

@knocte any input from your side?

knocte commented 4 years ago

https://stackoverflow.com/questions/6958255/what-are-some-reasons-networkstream-read-would-hang-block/6958290#6958290

That's about NetworkStream.Read(), the sync version, but you pointed above that it uses ReadAsync()?

wcypierre commented 4 years ago

The behaviour (in terms of if no data sent by the server) is the same apart from the sync version has a timeout while async version doesn't really have a proper timeout built in.

https://stackoverflow.com/questions/3466332/beginreceive-beginread-timeouts

I did a peek and for GetUserDialogsAsync(), the stream.DataAvailable is false, which indicates there's no data sent from the server so socket is stuck waiting for data (I did some loop to sleep until stream.DataAvailable == true but it didn't happened)

stream.DataAvailable is true for AuthUser and it works fine.

Probably need some other users to test and see if this is an isolated incident or others are facing it too

knocte commented 4 years ago

How about changing TLSharp to only call ReadAsync() when stream.DataAvailable is true?

wcypierre commented 4 years ago

I agree on that, that is one of the correct the stuck issue(that would make it throw the Couldn't read the packet length InvalidOperationException so at least the user of the library can handle it from his/her end or from the library's end.

Another one is to identify or even drop the DC that is not working for some reason

knocte commented 4 years ago

that would make it throw the Couldn't read the packet length InvalidOperationException

Throw anything is better than hanging! please propose a simple PR with that change and we take it from there.