Ich bin ein C# Telegramm-Client von TLSharp benutzerdefinierte Codierung starten und modifiziert sie, um Schicht 54Telegramm Client-Updates und API-Anfragen über derselben Sitzung
ich beide Empfangs Updates behandeln die von Telegramm-Servern und mit unterstützen wollen API ohne dafür eine separate Sitzung zu öffnen.
Das Problem ist im Grunde ein Multithread-Zugriff auf den Socket, der mit dem Telegram Server verbunden ist.
Hier ist es das Schema:
TelegramClient < ------- socket_1 [(session_1)] --------> TelegramServer
Das Problem ist, dass, um zu erhalten ständig aktualisiert von Telegramm-Server ich eine Weile (true) Zyklus verwenden, die im Grunde ist schematisiert als:
while(true){
data_cipher = await socket_1.receive() // listen for new stuff from the socket_1
data_plain = decrypt(data_cipher) // decrypt
processUpdate(data_plain) // process the update
}
Nun, wenn ich will, zum Beispiel Abfrage-Telegramm-Server für die Liste aller Chats, in denen bin ich registriert, ich habe um auf die socket_1 zuzugreifen, um diese Anfrage zu senden und auf die Antwort zu warten, aber socket_1 hört zu und ich kann natürlich nicht darauf zugreifen.
Eine Lösung könnte sein, einen Vektor der Anfrage zu verwenden, die verarbeitet werden, nachdem eine Aktualisierung empfangen wurde, die Idee, so etwas wie diese:
List<Request> pending_requests = new List<Request>() // list of requests added by another thread
while(true){
data_cipher = await socket_1.receive() // listen for new stuff from the socket_1
data_plain = decrypt(data_cipher) // decrypt
processUpdate(data_plain) // process the update
if(pending_requests.Count != 0){
foreach(Request r in pending_requests){
processRequest(r)
}
}
}
Diese Lösung ist ziemlich schrecklich, da wir einen Prozess Anfrage nur nach einem Update, und so kein Update = keine Anfrage bearbeitet ...
eine andere Möglichkeit, eine Art von Verriegelungsmechanismus nach einem Schema wie folgt verwenden könnte:
//Thread_updater
//--------------------------------------------
while(true){
lock(socket_1){
data_cipher = await socket_1.receive() // listen for new stuff from the socket_1
}
data_plain = decrypt(data_cipher) // decrypt
handleUpdate(data_plain) // process the update
}
--------------------------------------------
//Thread_requests
//--------------------------------------------
Request r = new Request(<stuff>);
lock(socket_1){
await sendRequest(r,socket_1)
}
--------------------------------------------
Das große Problem dabei ist, dass sobald der Thread_updater die Sperre übernimmt, diese erst wieder freigegeben wird, wenn ein Update empfangen wurde ... Dies ist im Grunde das gleiche Problem wie zuvor. Ich habe versucht, auch mit CancellationTasks oder Socket Timeout zu spielen, aber ich fühlte mich, als würde ich einen falschen Weg gehen.
Gibt es eine elegante Lösung/Muster, um dies auf eine saubere Art zu handhaben? Wie gesagt, ich möchte nicht 2 Sitzungen öffnen, da es logisch falsch ist (es wäre wie zwei Clients zu haben, um den Empfang von Updates und das Senden von Nachrichten zu behandeln).