socket_recv wirft (Fehler 104) "Connection reset by peer"

tempteam

Grünschnabel
Hallo Leute,

Ich bin schon am Verzweifeln, hab hier komische Phänomene, die ich mir nicht erklären kann. Ich hoffe, Ihr könnt mir weiter helfen.

Kurz zu der Aufgabe:

ich arbeite an einer Anwendung, wo parallel bis zu 150 Clients aktiv sind (kann auch mehr sein). Bei der Kommunikation setze ich selbst geschriebenes PHP-Websocket ein.

Zum Server:

OS: Ubuntu 16.04
PHP: 7.1.0RC1
Webserver: Nginx

Zu den Phänomenen:


Ab und zu spuckt socket_recv mir den 104 Fehler (Connection reset by peer) aus.
PHP:
                            // Receives data from a connected socket
                            $bytes = socket_recv($resource, $buffer, 4096, 0);
                            if ($bytes === FALSE) { // Received data has errors
                           
                                $errorMsg = 'socket_recv returns an error ' . socket_strerror(socket_last_error());
                                   
                                // Log to the log file
                                Logger::addData($errorMsg);
                                Logger::addData('Client ' . $address . ':' . $port);
                                Logger::toFile(self::LOG_FILE_NAME);
                           
                                // Console log
                                SocketHelper::writeLog(array($errorMsg, 'Error code ' . socket_last_error()));
                           
                                // Close connection
                                $this->_closeConnection(array('id' => $index, 'resource' => $resource));
                            }
                            else if ($bytes > 0) { // received data are fine
                           
                                // Console log
                                SocketHelper::writeLog(array('Received bytes ' . $bytes . ' from client ' . $address . ':' . $port));
                           
                                // Share date to the clients
                                Client::broadcastData($this->_getStorage(), array('id' => $index, 'resource' => $resource), $buffer, $bytes, $this->getModelByKey('domain'));
                           
                            }

Zuerst dachte ich, dass die Ressource verloren geht, aber beim Debuggen war sie immer da. Deswegen keine Ahnung was hier noch falsch laufen kann.

Und bei dem zweiten Phänomen, bleibt der Websocket-Server einfach nach einer XXX Zeit hängen. Auch in der Console passiert nix mehr. Erst nach dem man es über die Console neue startet, kann es weiter gehen.

Und das passiert meistens wenn der Socket sehr belastet wird.

Hat jemand Idee ?
 
Zuerst dachte ich, dass die Ressource verloren geht, aber beim Debuggen war sie immer da. Deswegen keine Ahnung was hier noch falsch laufen kann.

Habe damit nicht wirklich viel Erfahrung, aber „Connection reset by peer“ scheint auszusagen, dass der Client die Verbindung abbricht/beendet hat.

- http://stackoverflow.com/questions/1434451/what-does-connection-reset-by-peer-mean

Keine Ahnung, was da an Clients dranhängt. Könnte mir denken, dass so was passiert, wenn jemand ein Browsertab oder dergleichen schließt und vielleicht, wenn deine Anwendung zusätzlich noch versucht, an diesen Client zu broadcasten, der aber nicht mehr existiert?

Und bei dem zweiten Phänomen, bleibt der Websocket-Server einfach nach einer XXX Zeit hängen.

Wenn ich raten sollte: Irgendwas an deiner Socket-Kommunikation blockt und du läufst vielleicht in irgendeine Art von Deadlock. Da du Dinge mitloggst, solltest du ja vielleicht so halb in Erfahrung bringen können, an welcher Stelle es hakt. Vielleicht gehen dir einfach die Socket-Verbindungen aus, weil du vielleicht alte nicht richtig schließt oder weil einfach ein Limit erreicht wird? Könnte eine Konfigurationssache am Server sein. Ich weiß spontan nicht, wo man die Anzahl der Verbindungen einstellen kann. Schreib vielleicht die Anzahl der „aktiven“ Verbindungen mit ins Log. Vielleicht kommt dabei was raus, weil es immer bei ~150 hängt oder dergleichen. (Wenn du die passende Config-Einstellung dafür findest, kannst du den Maximalwert für Tests niedriger stellen. Dann ist das leichter nachzustellen.)

Alternativ die Lowlevel-Kommunikation vielleicht nicht selbst programmieren, sondern so was wie Ratchet nutzen.

- http://socketo.me/
 
Zuletzt bearbeitet:
Keine Ahnung, was da an Clients dranhängt. Könnte mir denken, dass so was passiert, wenn jemand ein Browsertab oder dergleichen schließt und vielleicht, wenn deine Anwendung zusätzlich noch versucht, an diesen Client zu broadcasten, der aber nicht mehr existiert?

Der Browsertab bleibt offen, dieser Fehler kommt "spontan", deswegen kann ich mir das Problem auch nicht erklären. Da die Ressource noch da ist.

Vielleicht gehen dir einfach die Socket-Verbindungen aus, weil du vielleicht alte nicht richtig schließt oder weil einfach ein Limit erreicht wird?

bei dem Socket habe ich eigentlich fast auf alle Limits verzichtet, die die ich habe habe ich schon hochgedreht. Aber so ein Verdacht hatte ich auch schon, dass hier einfach etwas voll läuft. Da es erst bei hoher Last und nach XXX Zeit passiert.

Dann bleibt mir nichts anderes als weiter zu suchen.

Vielen Dank für die schnelle Antwort:)
 
Hi

Falls es Firefox betrifft, der hat vermutlich einfach irgendeinen Fehler. Egal ob Websockets, Ajax, oder einfach ganz normale HTTP-Requests beim Seitenaufbau; ich seh das bei allen Arten immer wieder. Unabhängig von Website, Webserver, Client-OS, usw.
In dem Fall besser einfach die Symtome behandeln: So programmieren, dass Verbindungsabbrüche nicht zu Fehlerausgaben etc. führen und die Verbindung einfach wieder aufgebaut wird.
 
Problem 1:

socket_recv 104 Fehler, bei mir gehen soviel Daten rein, dass der Server es einfach nicht schaffte meine Arrays rechtzeitig zu leeren. Somit hatte er versucht eingehende Daten auch auf Sockets zuschreiben, die schon am abmelden waren.


Auch das zweite Problem konnte ich endlich nach drei Tagen finden. :rolleyes:

PHP:
$bytes = socket_recv($resource, $buffer, 4096, 0);

Sobald die eingehende Daten eine Längen mehr als "4096" haben, bleibt der Server einfach stehen, da er sie nicht bis zur Ende auslesen kann.
 

Neue Beiträge

Zurück