diff --git a/server/node.ws.js/run.sh b/server/node.ws.js/run.sh
new file mode 100644
index 0000000..2cf7563
--- /dev/null
+++ b/server/node.ws.js/run.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+while true
+do
+ echo "Running node"
+ node server.js $1
+done
diff --git a/server/node.ws.js/server.js b/server/node.ws.js/server.js
new file mode 100644
index 0000000..a6a64fb
--- /dev/null
+++ b/server/node.ws.js/server.js
@@ -0,0 +1,41 @@
+var sys = require("sys"),
+ ws = require("./ws");
+
+function broadcast(data, from) {
+ clients.forEach(function (client) {
+ if (client != from) {
+ try {
+ client.write(data);
+ } catch (e) {
+ clients.remove(client);
+ }
+ }
+ });
+}
+
+Array.prototype.remove = function(e) {
+ for (var i = 0; i < this.length; i++)
+ if (e == this[i]) return this.splice(i, 1);
+}
+
+var clients = [];
+
+ws.createServer(function (websocket) {
+ clients.push(websocket);
+
+ websocket.addListener("connect", function (resource) {
+ // emitted after handshake
+ sys.debug("connect: " + resource);
+ broadcast(clients.length+'');
+ }).addListener("data", function (data) {
+ // send data to attached clients
+ sys.puts('sending data...');
+ broadcast(data, websocket);
+ }).addListener("close", function () {
+ // emitted when server or client closes connection
+ sys.debug("close");
+ clients.remove(websocket);
+ broadcast(clients.length+'');
+ });
+}).listen(parseInt(process.ARGV[2]) || 8000);
+
diff --git a/server/node.ws.js/ws.js b/server/node.ws.js/ws.js
new file mode 100644
index 0000000..622d693
--- /dev/null
+++ b/server/node.ws.js/ws.js
@@ -0,0 +1,131 @@
+// Github: http://github.com/ncr/node.ws.js
+// Compatible with node v0.1.91
+// Author: Jacek Becela
+// License: MIT
+// Based on: http://github.com/Guille/node.websocket.js
+
+function nano(template, data) {
+ return template.replace(/\{([\w\.]*)}/g, function (str, key) {
+ var keys = key.split("."), value = data[keys.shift()];
+ keys.forEach(function (key) { value = value[key] });
+ return value;
+ });
+}
+
+var sys = require("sys"),
+ net = require("net"),
+ headerExpressions = [
+ /^GET (\/[^\s]*) HTTP\/1\.1$/,
+ /^Upgrade: WebSocket$/,
+ /^Connection: Upgrade$/,
+ /^Host: (.+)$/,
+ /^Origin: (.+)$/
+ ],
+ handshakeTemplate = [
+ 'HTTP/1.1 101 Web Socket Protocol Handshake',
+ 'Upgrade: WebSocket',
+ 'Connection: Upgrade',
+ 'WebSocket-Origin: {origin}',
+ 'WebSocket-Location: ws://{host}{resource}',
+ '',
+ ''
+ ].join("\r\n"),
+ policy_file = '';
+
+exports.createServer = function (websocketListener) {
+ return net.createServer(function (socket) {
+ socket.setTimeout(0);
+ socket.setNoDelay(true);
+ socket.setEncoding("utf8");
+
+ var emitter = new process.EventEmitter(),
+ handshaked = false,
+ buffer = "";
+
+ function handle(data) {
+ buffer += data;
+
+ var chunks = buffer.split("\ufffd"),
+ count = chunks.length - 1; // last is "" or a partial packet
+
+ for(var i = 0; i < count; i++) {
+ var chunk = chunks[i];
+ if(chunk[0] == "\u0000") {
+ emitter.emit("data", chunk.slice(1));
+ } else {
+ socket.end();
+ return;
+ }
+ }
+
+ buffer = chunks[count];
+ }
+
+ function handshake(data) {
+ var headers = data.split("\r\n");
+
+ if(//.exec(headers[0])) {
+ socket.write(policy_file);
+ socket.end();
+ return;
+ }
+
+ var matches = [], match;
+ for (var i = 0, l = headerExpressions.length; i < l; i++) {
+ match = headerExpressions[i].exec(headers[i]);
+
+ if (match) {
+ if(match.length > 1) {
+ matches.push(match[1]);
+ }
+ } else {
+ socket.end();
+ return;
+ }
+ }
+
+ socket.write(nano(handshakeTemplate, {
+ resource: matches[0],
+ host: matches[1],
+ origin: matches[2],
+ }));
+
+ handshaked = true;
+ emitter.emit("connect", matches[0]);
+ }
+
+ socket.addListener("data", function (data) {
+ if(handshaked) {
+ handle(data);
+ } else {
+ handshake(data);
+ }
+ }).addListener("end", function () {
+ socket.end();
+ }).addListener("close", function () {
+ if (handshaked) { // don't emit close from policy-requests
+ emitter.emit("close");
+ }
+ });
+
+ emitter.remoteAddress = socket.remoteAddress;
+
+ emitter.write = function (data) {
+ try {
+ socket.write('\u0000', 'binary');
+ socket.write(data, 'utf8');
+ socket.write('\uffff', 'binary');
+ } catch(e) {
+ // Socket not open for writing,
+ // should get "close" event just before.
+ socket.end();
+ }
+ }
+
+ emitter.end = function () {
+ socket.end();
+ }
+
+ websocketListener(emitter); // emits: "connect", "data", "close", provides: write(data), end()
+ });
+}