Seite 7 von 9

Re: WebSocket Server

Verfasst: 02.04.2025 16:41
von Dadido3
stevie1401 hat geschrieben: 02.04.2025 13:05 Ich habe mit Spiderbasic einen Code geschrieben, der viele Clients anmeldet und die dann etwas senden.
Wenn ich während die Clients sich anmelden das Browserfenster von der Spiderbasic-App schliesse, dann verabschiedet sich der Webserver ins Nirvana.
Im unteren Beispiel soll das Spider-Client-Programm 400 Clients anmelden. Im Debugfenster des Browsers sehe ich welcher Client schon angemeldet ist.
Wenn ich jetzt mittendrin, zum z.B. bei Client 100 das Browserfenster einfach schließe, verabschiedet sich der Server.

Ich habe dies mit allen Servern getestet, dem Threadlosen und die beiden aktuellen mit Threads.
Leider habe ich hier kein Spiderbasic und kann den Code nicht testen. Aber ich habe folgenden Code um den Server zu testen:

https://github.com/Dadido3/WebSocket_Se ... StressTest

Hiermit konnte ich aber auch mit bis zu 1000 Clients, welche alle connecten, verschiedene Nachrichten senden/empfangen und reconnecten, keinen Crash herbeiführen. Eventuell kannst du ja mal mit deinem Spiderbasic-Code versuchen StressTest.pb zum Absturz zu bringen. Der StressTest.pb Testserver macht nichts anderes als Verbindungen entgegenzunehmen und empfangene Websocket-Pakete wieder zurückzusenden.
stevie1401 hat geschrieben: 02.04.2025 13:05 Ich habe auch festgestellt, dass die

Procedure Frame_Text_Send(*Object.Object, *Client.Client, Text.s)

NICHT prüft, ob es den Client an den es senden soll überhaupt gibt.

Ob es dafür eine Lösung gibt?

Code: Alles auswählen

Procedure Frame_Text_Send(*Object.Object, *Client.Client, Text.s)
prüft absichtlich nicht ob der *Client vorhanden ist. Das wäre viel zu rechenaufwändig, da dafür entweder über die Liste mit den Clients iteriert werden müsste, oder aber extra eine Map mit den Clients gepflegt werden müsste. Daher darf der entsprechende *Client nicht mehr verwendet werden, sobald dieser disconnected ist. Dies ist auch im Eventhandler des Beispielcodes auf GitHub so dargestellt:

Code: Alles auswählen

...
    Case WebSocket_Server::#Event_Disconnect
        PrintN(" #### Client disconnected: " + *Client)
        ; !!!! From the moment you receive this event *Client must not be used anymore !!!!
...
Genaugenommen ist der Client exakt dann nicht mehr gültig, nachdem der Eventhandler verlassen wurde. Das heißt es führt nicht zu Problemen wenn im Hintergrund noch Daten an diesen gesendet werden während man den Event entgegennimmt. Man sollte aber sobald man WebSocket_Server::#Event_Disconnect empfängt dafür sorgen, dass nach dem Verlassen des Eventhandlers keine weiteren API-Aufrufe (Frame_Text_Send, Frame_Send, ...) mit diesem *Client ausgeführt werden. Andernfalls führt dies zu undefiniertem Verhalten und Speicherzugriffsfehlern.

Eventuell könntest du zum Debuggen mal den *Client mitloggen. Verändere dafür einfach mal das Include auf folgende Weise:

Code: Alles auswählen

Procedure Frame_Send(*Object.Object, *Client.Client, FIN.a, RSV.a, Opcode.a, *Payload, Payload_Size.q)
    PrintN("Called Frame_Send on Client " + *Client)
    ...
EndProcedure

Code: Alles auswählen

      ...
      ; #### Event: Client connected and handshake was successful.
      If *Client\Event_Connect
        PrintN("New connection from Client " + *Client)
        ...
Folgendes kommt 2 mal im Include vor:

Code: Alles auswählen

        ...
        ; #### Delete the client and all its data.
        PrintN("Starting to invalidate Client " + *Client)
        ClientQueueRemove(*Object, *Client)
        Client_Free(*Client)
        ChangeCurrentElement(*Object\Client(), *Client)
        DeleteElement(*Object\Client())
        PrintN("Invalidated Client " + *Client)
        Break
        ...
Hierbeit sollte dann "Called Frame_Send on Client xxx" nur zwischen den entsprechenden Meldungen "New connection from Client xxx" und "Starting to invalidate Client xxx" erscheinen. Andernfalls nutzt du einen *Client, welcher nicht mehr Gültig ist.

Re: WebSocket Server

Verfasst: 02.04.2025 22:32
von stevie1401
Ich habe ja schon einen Streßtest mit deinen Servern mit meinem Spiderbasic-Code gemacht.
Da verbinde ich Clients, die dann nur an den Server etwas senden, mehr nicht. Sie senden NICHT an andere Clients.
Und dennoch geht der Server ab ins Nirvana und bei neueren Test kommen zudem tatsächlich auch wieder Speicherfehler, ob wohl ich NICHT an andere Clients sende.
Wie gesagt, ich benutze die Original Beispiel-Codes, die du zur Verfügung stellst.

Dennoch:
Vielen Dank dür deine Tips, ich werde das testen.
Mit den Maps zur Prüfung, ob der Client überhaupt vorhanden ist, ist eine tolle Idee, ich versuche einmal das selber hinzubekommen.
Ansonsten bin ich langsam ratlos.
Ich arbeite ohne Thread und mache nichts von deinem Beschriebenem, was den Server zu Absturz bringen könnte.
Ich habe "das Gefühl", dass, wenn ein Client sich gerade verbinden will und während dieser Procedure das Internet abbricht, der Server ins Nirvana geht.
Ich wüsste nicht, wie ich das verhindern sollte und könnte.
Wie den auch sei, ich werde weiter tüfteln und testen und werde berichten :)

Die Testversion von Spiderbasic bekommst du hier:
https://www.spiderbasic.com/
Die langt, um meinen Code auszuführen.

Re: WebSocket Server

Verfasst: 02.04.2025 23:35
von Dadido3
stevie1401 hat geschrieben: 02.04.2025 22:32 Mit den Maps zur Prüfung, ob der Client überhaupt vorhanden ist, ist eine tolle Idee, ich versuche einmal das selber hinzubekommen.
Das mit den Maps kannst du natürlich testen, aber eine dauerhafte Lösung wäre das meiner Meinung nach nicht. Aber wenn auch die Beispiele von dem Problem betroffen sind, müsste es an etwas anderem liegen. Gerade der Stress-Test server ist ziemlich einfach aufgebaut.
stevie1401 hat geschrieben: 02.04.2025 22:32 Die Testversion von Spiderbasic bekommst du hier:
https://www.spiderbasic.com/
Die langt, um meinen Code auszuführen.
Ich habe jetzt mal die Demo runtergeladen, aber auch mit deinem Testcode bekomme ich weder den Chat-Server noch den Stress-Test-Server zum abstürzen (Weder in der threadless noch in der regulären Variante). Auch mehrmaliges Öffnen und Schließen des Tabs zu verschiedenen Zeitpunkten hat keinen Fehler verursacht.

Kannst du mir noch ein paar Details zu deiner Umgebung nennen? Mindestens:
  • PB-Version
  • Compiler
  • Zielarchitektur (x86 oder x86-64)
  • Browser aus dem du zum Ausführen deines Testcodes verwendest
  • Betriebssystem
stevie1401 hat geschrieben: 02.04.2025 22:32 Ich habe "das Gefühl", dass, wenn ein Client sich gerade verbinden will und während dieser Procedure das Internet abbricht, der Server ins Nirvana geht.
Ich wüsste nicht, wie ich das verhindern sollte und könnte.
Da gibt es theoretisch nichts was du verhindern musst, der Server ist dafür gemacht dies korrekt zu handhaben. Aber um das Problem wirklich einzugrenzen, muss ich es erst reproduzieren können.

Re: WebSocket Server

Verfasst: 03.04.2025 08:21
von stevie1401
Ich habe jetzt deinen threadlosen Stresstestserver getestet.
Der funktioniert.

Ich arbeite mit Purebasic 6.20 auf Linux Mint bzw Debian12, x64
Der Compiler ist Linux x64
Ich teste mit Chromium. Aber die Leute auf meiner Plattform spielen natürlich mit allen möglichen Browsern.

Ich habe jetzt Maps eingebaut.
Damit zeigt mir der Server zwar, dass an einen Client gesendet wird, den es nicht gibt und gibt auch KEINEN Speicherfehler mehr aus, verabschiedet sich aber dennoch ins Nirvana.
Das passiert dann aber nur dann, wenn ich sage, ein Client, der sich anmeldet, solll an alle Clients mal "Hallo" sagen.
Da ich dieses an alle senden nicht in einem extra Thread mache, wüsste ich nicht, was ich da falsch machen sollte.


Ich habe die Zeilen eingefügt:

Code: Alles auswählen


 ; #### Delete the client and all its data.
        PrintN("Starting to invalidate Client " + *Client)
        ClientQueueRemove(*Object, *Client)
        Client_Free(*Client)
        ChangeCurrentElement(*Object\Client(), *Client)
        DeleteElement(*Object\Client())
        PrintN("Invalidated Client " + *Client)
        Break

Unter Linux bekomme ich KEINE Nachricht und der Server stürzt wie beschrieben ab.
Unter Windows bekomme ich die Meldungen "Starting to invalidate Client" und "Invalidated Client" und der Server stürzt NICHT ab.
Es scheint also ein Linuxproblem zu sein!

Re: WebSocket Server

Verfasst: 03.04.2025 11:21
von Dadido3
Alles klar, ich werde es auch nochmal unter linux testen.

Re: WebSocket Server

Verfasst: 03.04.2025 11:30
von dige
@Dadido3: Stevie beschreibt meines ernachtens nach ein Szenario, bei dem Clients plötzlich hart weg sind, ohne das es ein sauberes Disconnect gab. D.h. der Stressstess müsste so gebaut sein, dass für eine Verbindung ein Thread gestart und eine Websocket Verbindung aufbaut wird.
Das Hauptprogramm müsste dann den Thread nach einer bestimmten Zeit hart killen. Damit wäre dann der Bug vielleicht reproduzierbar?
Nur mal so als Gedanke.. ich habe jetzt nur flüchtig über Eure Konversation geschaut

Re: WebSocket Server

Verfasst: 03.04.2025 13:21
von Dadido3
Dadido3 hat geschrieben: 03.04.2025 11:21 ich werde es auch nochmal unter linux testen.
Ich konnte jetzt auch unter Linux (Debian 12, x64) mit Purebasic 6.20 x64 das Problem nicht nachbilden. Auch mit deinem SpiderBasic-Client, welchen ich viele Male gestartet und hart gestoppt habe.
dige hat geschrieben: 03.04.2025 11:30 @Dadido3: Stevie beschreibt meines ernachtens nach ein Szenario, bei dem Clients plötzlich hart weg sind, ohne das es ein sauberes Disconnect gab. D.h. der Stressstess müsste so gebaut sein, dass für eine Verbindung ein Thread gestart und eine Websocket Verbindung aufbaut wird.
Das Hauptprogramm müsste dann den Thread nach einer bestimmten Zeit hart killen. Damit wäre dann der Bug vielleicht reproduzierbar?
Nur mal so als Gedanke.. ich habe jetzt nur flüchtig über Eure Konversation geschaut
Soweit habe ich das auch verstanden. Und die Versuche die ich unternommen habe dies zu reproduzieren sollten das eigentlich abdecken. Ich habe den Stress-Test Client zu verschiedenen Zeitpunkten beendet/gekillt, und das Selbe auch mit dem SpiderBasic Test-Client von stevie1401 versucht. Leider bisher ohne Erfolg.

@stevie1401: Könntest du ein Minimalbeispiel hochladen, welches das Problem zeigt? Also ein komplettpaket aus dem Include welches du verwendest, dem Server-Code, und dem SpiederBasic-Client. Wenn es geht möglichst wenig abweichend zu dem Code auf GitHub.

Re: WebSocket Server

Verfasst: 03.04.2025 15:56
von stevie1401
Ich habe auf 3 Rechnern hier bei mir zuhause und auf einem virtuellen Rechner bei Netcup folgendes gemacht:

Ich habe mit Purebasic 6.20 die Datei Example_Chat_Server aus dem Verzeichnis Websocket_Server_master geladen und gestartet.

Dann habe ich meinen Bot-Code, welchen ich hier gepostet habe, mit Spiderbasic geladen und gestartet.

Ich habe keinerlei an den Files geändert!
Ich habe das Aufzählen und Connecten der Clients gewaltsam unterbrochen, indem ich den Browser schloß.

Das Ergebnis war auf allen Rechnern gleich:

Der Server ging ins Nirvana und die Purebasic-IDE bemerkte es nicht einmal.

Ab und zu geht der Server bei den ersten Malen NICHT ins Nirvana. Dann bekomme ich allerdings plötzlich eine CPUauslastung von 100%, die erst dann runtergeht, wenn ich den Server beende.

Mehr kann ich eigentlich nicht mehr dazu sagen.

Re: WebSocket Server

Verfasst: 03.04.2025 16:09
von dige
Habs jetzt auch mal mit der aktuellen Purebasic 6.21 Beta 3 getestet und Stevies Code mit SpiderBasic 3.0.2.
Lief alles tutti paletti.
Sobald der Browser geschlossen bzw. über den Taskmanager gekillt wird, werden vom Server die Verbindungen als Disconnected angezeigt.

Re: WebSocket Server

Verfasst: 03.04.2025 17:19
von Dadido3
@stevie1401 ich glaube dir ja, dass dies bei dir Abstürze hervorruft. Aber ich kann das hier nicht nachvollziehen. Ich habe jetzt so ziemliche viele Kombinationen der folgenden Sachen probiert:

- PureBasic 6.04 LTS x64 unter Windows 11 26100, PureBasic 6.04 LTS x86 unter Windows 11 26100, PureBasic 6.04 LTS - C Backend x64 unter Windows 11 26100, PureBasic 6.20 x64 unter Debian 12 x64
- Mit/ohne debugger, mit/ohne Purifier
- Include mit Threads, und ohne Threads
- Example_Chat_Server.pb, StressTest.pb
- Deinen SpiderBasic-Client, meinen StressTest-Client

Ich habe jetzt die Test-Clients bestimmt 100-200 mal gestartet/neu gestartet/zwangsgestoppt. Aber es kam kein einziges mal zu einem Absturz. Es muss noch irgendeinen anderen Unterschied zwischen beiden Testaufbauten geben. Deswegen schick einfach mal die 3-4 Dateien für den Server und Client die das Problem aufzeigen (Auch wenn es nur die Originaldateien sind), am besten auch dazu beschreiben ob der Debugger an ist, der Purifier aktiv ist und alles weitere. Wahrscheinlich mache ich irgendetwas subtil anders, und bekomme deswegen andere Ergebnisse.