2015-01-04 4 views
23

Ich habe Probleme mit meinem node.js Hobby-Projekt aufgrund eines "schreibe nach Ende" -Fehlers. Ich habe einen einen node.js Webserver, der unter anderem erstellt, von einer HTML-Seite sendet weiter an einem anderen Prozess empfangenen Befehle mit dem folgenden Code:Schreiben nach Ende Fehler in node.js Webserver

var netSocket = require('net').Socket(); 
netSocket.connect(9090); 
netSocket.write(messages); 
netSocket.end(); 

Das funktioniert, bis der Verkehr zu erhöhen beginnt (dh die Menge an Nachrichten gesendet werden und oder die Größe der Nachrichten). An dieser Stelle bekomme ich folgende Fehlermeldung:

Error: write after end 
    at writeAfterEnd (_stream_writable.js:132:12) 
    at Socket.Writable.write (_stream_writable.js:180:5) 
    at Socket.write (net.js:615:40) 
    at Socket.<anonymous> (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/speech_module/web_server_HTTPS.js:66:15) 
    at Socket.emit (events.js:95:17) 
    at Socket.onevent (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/node_modules/socket.io/lib/socket.js:327:8) 
    at Socket.onpacket (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/node_modules/socket.io/lib/socket.js:287:12) 
    at Client.ondecoded (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/node_modules/socket.io/lib/client.js:193:14) 
    at Decoder.Emitter.emit (/Users/mark/Documents/GitHub Repos/voice_controlled_zumo/node_modules/socket.io/node_modules/socket.io-parser/node_modules/component-emitter/index.js:134:20) 

Meine Vermutung ist, dass der Server in 9090 wird durch die Menge des Verkehrs, überwältigt zu werden, zu dem Fehler führt. Als ein kompletter Neuling in der node.js-Welt würde ich mich über Hinweise freuen, wie ich dieses Problem lösen könnte.

Beachten Sie auch, dass der Webserver Seiten über SSL bereitstellt (falls dies einen Unterschied macht).

Danke, dass Sie sich die Zeit genommen haben, dies zu lesen!

Mark

+0

Nun, Sie uns das Socket-Client gezeigt haben, aber wo ist die Code-Server? Kannst du uns das zeigen? – jakerella

Antwort

30

node.js ist eine nicht-blockierende Asynchron-Plattform.

In Ihrem Fall

netSocket.write(messages); 

ist eine Async Methode daher netSocket.end() vor 'write' genannt wird, ist abgeschlossen.

die korrekte Verwendung wäre:

netSocket.write(messages, function(err) { netSocket.end(); }); 

Das zweite Argument ist hier eine Callback-Funktion, die einmal die Methode seine Arbeit beendet ‚schreiben‘ genannt wird.

Ich würde Ihnen empfehlen, mehr über node.js, asynchrone Stile und Rückrufe zu lesen/sehen.

hier ist ein großartiger Ort zu starten: https://www.youtube.com/watch?v=GJmFG4ffJZU

Und natürlich die node.js API docs in Bezug auf Netto-Sockets.

Hope it :) half

+0

Danke für die schnelle Antwort! Ich werde das heute nach Feierabend ausprobieren und komme wieder zu dir! – Mark

+0

Nach dieser Änderung kommt der Fehler seltener. Deshalb markiere ich diese Frage als beantwortet, weil die Antwort mir geholfen hat und relevant war. – Mark

+0

Das war wirklich augenöffnend, danke Ron. Aber zwei Fragen/Kommentare: 1. Node eigene docs Aufruf "Ende" sofort, nicht auf den 'write' Rückruf: https://nodejs.org/api/http.html#http_http_request_options_callback 2. Wenn Sie ' Wenn Sie mehrere 'write'-Aufrufe ausführen, bedeutet dies, dass Sie selbst eine ganze Reihe von Zuständen verwalten müssen? –

8

Erstens, ich denke, dass es Fehlinformationen in einer anderen Antwort über socket.write() und socket.end() ist. Es ist völlig normal und in Ordnung, sie zu tun, um wieder in dem gleichen tick nach hinten:

socket.write(everythingIPlanToSend); 
socket.end(); 

Sie können einen Rückruf write zur Verfügung stellen müssen. Der Rückruf sagt Ihnen, wann die Daten vollständig aus der Verbindung entfernt wurden, aber dies ist eine optionale Benachrichtigung, mit der sich typische Programme nicht befassen müssen.

Mit Blick auf Ihre Stack-Trace, denke ich, dass Ihre Ereignisbehandlung Kontrollfluss auf diese Weise unterbrochen ist. Sie haben einen socket.io-Client verbunden, und dieser sendet Ereignisse aus, auf die Sie achten. Wenn diese Ereignisse ausgelöst werden, senden Sie sie an Ihren Upstream-Server. Dann beenden Sie die Upstream-Socket-Verbindung. An diesem Punkt müssen Sie den Verbindungs-Listener socket.io (removeListener) freigeben, damit Sie nicht mehr versuchen, die Verbindung, die Sie bereits geschlossen haben, zu senden, wenn mehr Ereignisse eintreffen.

Eine andere Möglichkeit zu sagen ist, wenn Sie .end() auf Ihrem Upstream-Socket aufrufen, müssen Sie sicherstellen, dass zukünftige eingehende Ereignisse aus dem Browser diesen Socket nicht verwenden. ODER Sie müssen Ihren Code ändern, um den gleichen Upstream-Socket für alle Ereignisse aus dem entsprechenden Browser-Socket zu verwenden (was wahrscheinlich effizienter/korrekter ist), aber rufen Sie .end() nicht auf, bis der Browser-Socket tatsächlich getrennt wird.

0

Ich hatte ähnliches Problem mit Knotenmodul Kompression, nachdem ich es auf die neueste Version 1.6 zu aktualisieren, wurde das Problem

aufgelöst
npm install [email protected] 
Verwandte Themen