Mark
Mark

Reputation: 465

Write After End error in node.js webserver

I am struggling with my node.js hobby project due to a "write after end" Error. I have a created a node.js webserver that amongst other things, sends commands received from a HTML page onwards to another process using the following code:

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

This works until the traffic starts to increase (i.e. the amount of messages being sent and or the size of the messages). At this point I get the following error:

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)

My guess is that the server at 9090 is being overwhelmed by the amount of traffic, giving rise to the error. As a complete newbie in the node.js world I'd really appreciate any hints for how I could resolve this issue.

Note also that the webserver is serving pages over SSL (in case that makes any difference).

Thanks for taking the time to read this!

Mark

Upvotes: 38

Views: 105374

Answers (4)

Skkkhsn Jjjskshs
Skkkhsn Jjjskshs

Reputation: 19

Try to put "await" if missed.

Upvotes: -1

Ron Bar
Ron Bar

Reputation: 510

NodeJS is a non-blocking async platform.

In your case,

netSocket.write(messages);

is an async method; therefore, netSocket.end() is called before write is complete.

The correct use would be:

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

The second argument here is a callback function that will be called once the 'write' method finishes its job.

I would recommend you read/watch more about NodeJS, async styles and callbacks.

Here is a great place to start: https://www.youtube.com/watch?v=GJmFG4ffJZU

And of course, the NodeJS API docs regarding net sockets.

Upvotes: 47

shacharsol
shacharsol

Reputation: 2342

I had similar issue with node module compression, after i update it to the latest version 1.6, the issue was resolved

npm install [email protected]

Upvotes: 1

Peter Lyons
Peter Lyons

Reputation: 146064

First, I think there is misinformation in another answer about socket.write() and socket.end(). It is perfectly normal and OK to do them back to back in the same tick:

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

You do not need to provide a callback to write. The callback will tell you when the data has been fully flushed out the connection, but that is an optional notification that typical programs don't need to concern themselves with.

However, looking at your stack trace, I think your event handling control flow is broken in this manner. You have a socket.io client connected, and that emits events which you listen for. When those events fire you send them onward to your upstream server. Then you end the upstream socket connection. At that point, you must unbind (removeListener) your socket.io connection listener so that as more events arrive you don't attempt to send them up the connection you have already closed.

Another way to say it is whenever you call .end() on your upstream socket, you have to make sure that future incoming events from the browser do not make use of that same socket. OR you have to change your code to use the same upstream socket for all events from the corresponding browser socket (which is probably more efficient/correct), BUT in that case don't call .end() on it until the browser socket actually disconnects.

Upvotes: 24

Related Questions