Permalink
Browse files

websocket.Server: first try

With a new example/chat.js
  • Loading branch information...
1 parent a53c9f1 commit 426a4f8337657b3ca41b8fcc3891cbf49fbad658 @zimbatm committed Dec 26, 2009
Showing with 147 additions and 3 deletions.
  1. +86 −0 example/chat.js
  2. +61 −3 lib/http/websocket.js
View
@@ -0,0 +1,86 @@
+#!/usr/bin/env node
+
+// Devel mode
+require.paths.unshift('../lib');
+
+var http = require('http'),
+ ws = require('http/websocket'),
+ posix = require('posix'),
+ sys = require('sys');
+
+const publicDir = './public';
+
+function ping(msg, conn) {
+ sys.debug("PING: " + msg);
+ conn.send(msg);
+}
+
+function notFound(req, res) {
+ var msg = "<h1>File not found : " + req.uri.path + "</h1>";
+ res.sendHeader(404, {
+ "Content-Type": "text/html",
+ "Content-Length": msg.length
+ });
+ res.sendBody(msg);
+ res.finish();
+}
+
+var mimeReg = /\.[^\.]+$/
+mimeMap = {
+ ".html": "text/html",
+ ".js": "text/javascript",
+ ".xml": "application/xml",
+ ".swf": "application/x-shockwave-flash"
+}
+
+function sendFile(req, res, path) {
+ var data;
+ try {
+ data = posix.cat(path, "binary").wait();
+ if (data) {
+ var cType = mimeMap[mimeReg.exec(path)[0]] || "application/octet-stream";
+ res.sendHeader(200, {
+ "Content-Length": data.length,
+ "Content-Type": cType
+ });
+ res.sendBody(data, "binary");
+ res.finish();
+ return;
+ }
+ } catch(e) {
+ sys.debug(e);
+ }
+
+ sys.debug("File not found: " + path);
+ notFound(req, res);
+}
+
+var chat = new ws.Server();
+chat.addListener("connect", function(conn) {
+ sys.debug("onconnect");
+ this.broadcast("new connection: " + conn.remoteAddress);
+});
+chat.addListener("disconnect", function(conn) {
+ sys.debug("ondisconnect");
+ this.broadcast("disconnection of " + conn.remoteAddress);
+})
+chat.addListener("message", function(msg, conn) {
+ sys.debug("onmessage");
+ this.broadcast("Got " + msg);
+});
+
+function handler(req, res) {
+ sys.debug(req.method + ' ' + req.uri.path);
+ if (ws.askUpgrade(req)) {
+ sys.debug("Upgrading to WebSocket");
+ chat.connect(req, res);
+ } else {
+ var filePath = publicDir + req.uri.path;
+ sendFile(req, res, filePath);
+ }
+}
+
+var srv = http.createServer();
+srv.addListener("request", handler);
+srv.listen(8000);
+sys.puts("Connected on port :8000");
View
@@ -9,7 +9,9 @@ function askUpgrade(req) {
return supportUpgrade(req) && (req.headers.connection == 'Upgrade' && req.headers.upgrade == 'WebSocket');
}
-// Hijack HTTP connection
+/*
+websocket.Connection
+*/
function Connection(request, response) {
process.EventEmitter.call(this);
@@ -55,13 +57,69 @@ function Connection(request, response) {
sys.inherits(Connection, process.EventEmitter);
Connection.prototype.send = function(data) {
- this.connection.send('\u0000' + data + '\uffff');
+ if (this.connection.readyState == "open" || this.connection.readyState == "writeOnly") {
+ this.connection.send('\u0000' + data + '\uffff');
+ return true;
+ }
+ return false;
}
Connection.prototype.close = function() {
this.emit("close");
}
+/*
+websocket.Server
+*/
+function Server() {
+ process.EventEmitter.call(this);
+}
+sys.inherits(Server, process.EventEmitter);
+
+Server.prototype.connections = [];
+
+Server.prototype.connect = function(request, response) {
+ var self = this;
+ var conn = new Connection(request, response);
+ conn.addListener("message", function(msg) {
+ self.emit("message", msg, conn);
+ });
+ conn.addListener("disconnect", function() {
+ self.disconnect(conn);
+ });
+ this.connections.push(conn);
+ this.emit("connect", conn);
+}
+
+Server.prototype.disconnect = function(connection) {
+ if (maybeRemove(this.connections, connection)) {
+ connection.close();
+ this.emit("disconnect", connection);
+ }
+}
+
+Server.prototype.broadcast = function(msg) {
+ for (i in this.connections) {
+ this.connections[i].send(msg);
+ }
+}
+
exports.askUpgrade = askUpgrade;
-exports.Connection = Connection;
+exports.Connection = Connection;
+exports.Server = Server;
+
+
+// Utils
+
+function maybeRemove(arr, elem) {
+ for (var i=0; i<arr.length; i++) {
+ if (arr[i] == elem) {
+ sys.p(arr);
+ arr.splice(i, 1);
+ sys.p(arr);
+ return true;
+ }
+ }
+ return false;
+}

0 comments on commit 426a4f8

Please sign in to comment.