Sepoto Sepoto - 2 months ago 22
Node.js Question

Deleting websocket connections in JavaScript with NodeJS

#!/usr/bin/env node
var WebSocketServer = require('websocket').server;
var http = require('http');

var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});

wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});

function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
var jConnections = new Array();
wsServer.on('request', function(request) {

if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}

var connection = request.accept('echo-protocol', request.origin);
var jConnectionIdentity = new Date();
jConnections.push(new Array(connection,jConnectionIdentity) );
//console.log("datestamp"+jConnections[0][1]);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
//connection.sendUTF(message.utf8Data);
for(var i=0;i<jConnections.length;i++)
{
var jConnection = jConnections[i][0];
jConnection.sendUTF(message.utf8Data);
}
}
else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
//connection.sendBytes(message.binaryData);
for(var i=0;i<jConnections.length;i++)
{
var jConnection = jConnections[i][0];
jConnection.sendBytes(message.binaryData);
}
}
});
connection.on('close', function(reasonCode, description) {

for(var i=0;i<jConnections.length;i++)
{
if(jConnections[i][1] == jConnectionIdentity)
{
delete jConnections[i];
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
console.log(jConnections.length);
}
}
});
});


If I open 3 client connections and send a message from each client and then close the third client I am seeing that the output of "console.log(jConnections.length);" is still three. Upon closing the third client and sending a message from client two a crash of NodeJS occurs. My console output looks like this:

C:\Program Files\nodejs>node.exe workingexample3.js
Mon May 20 2013 16:30:14 GMT-0700 (Pacific Daylight Time) Server is listening on port 8080
Mon May 20 2013 16:30:18 GMT-0700 (Pacific Daylight Time) Connection accepted.
Mon May 20 2013 16:30:20 GMT-0700 (Pacific Daylight Time) Connection accepted.
Mon May 20 2013 16:30:22 GMT-0700 (Pacific Daylight Time) Connection accepted.
Received Message: client1
Received Message: client2
Received Message: client3
Mon May 20 2013 16:30:43 GMT-0700 (Pacific Daylight Time) Peer 127.0.0.1 disconnected.
3
Received Message: client2

C:\Program Files\nodejs\workingexample3.js:48
var jConnection = jConnections[i][0];
^
TypeError: Cannot read property '0' of undefined
at WebSocketConnection.<anonymous> (C:\Program Files\nodejs\workingexample3.js:48:38)
at WebSocketConnection.EventEmitter.emit (events.js:95:17)
at WebSocketConnection.processFrame (C:\Program Files\nodejs\node_modules\websocket\lib\WebSocketConnection.js:403:26)
at WebSocketConnection.handleSocketData (C:\Program Files\nodejs\node_modules\websocket\lib\WebSocketConnection.js:247:14)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket.<anonymous> (_stream_readable.js:736:14)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:408:10)
at emitReadable (_stream_readable.js:404:5)
at readableAddChunk (_stream_readable.js:165:9)

C:\Program Files\nodejs>


I was hoping that upon the delete statement the value of jConnections.length would be decreasing by one but that does not seem to be happening. Since all three of my clients are connecting from localhost 127.0.0.1 I had to come up with a plan to identify each connection by something other than the remoteAdress property. That's why I am pushing a Date in addition to the connection object. I am hoping to id each connection by the Date it was created on.

Answer

1) After you call delete your array looks like this -

[[1, 1], [2, 2], undefined]

The length is still 3 :)