qws
Version:
An HTML5 Web Sockets Server Module
196 lines (176 loc) • 4.87 kB
JavaScript
// Generated by CoffeeScript 1.9.2
var EventEmitter, Frame, Message, inflate, os, ref, unpack, zlib,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
os = require('options-stream');
zlib = require('zlib');
EventEmitter = require('events').EventEmitter;
ref = require('./frame'), unpack = ref.unpack, inflate = ref.inflate, Frame = ref.Frame;
Message = (function(superClass) {
extend(Message, superClass);
function Message(socket1, options) {
var frame, socket;
this.socket = socket1;
this.options = os({
deflate: true,
min_deflate_length: 32,
close_timeout: 100
}, options);
frame = null;
socket = this.socket;
this.inflate = zlib.createInflateRaw({
chunkSize: 128 * 1024
});
socket.on('data', (function(_this) {
return function(chunk) {
var ref1, results;
results = [];
while (chunk && chunk.length) {
ref1 = unpack(chunk, frame), frame = ref1[0], chunk = ref1[1];
if (frame.done) {
inflate(frame, _this.inflate, function(err, f) {
if (err) {
return _this.emit('error', err);
}
return _this.onFrame(f);
});
results.push(frame = null);
} else {
results.push(void 0);
}
}
return results;
};
})(this));
socket.on('error', (function(_this) {
return function(err) {
return _this.emit('error', err);
};
})(this));
socket.on('close', (function(_this) {
return function() {
return _this.emit('close');
};
})(this));
}
Message.prototype.write = function(data, opcode, mask, cb) {
var frame;
if (typeof mask === 'function') {
cb = mask;
mask = null;
}
switch (typeof opcode) {
case 'function':
cb = opcode;
opcode = null;
break;
case 'boolean':
mask = opcode;
opcode = null;
}
if (opcode == null) {
opcode = 'text';
}
if (mask == null) {
mask = false;
}
frame = new Frame({
data: data,
opcode: opcode,
fin: true,
mask: mask,
minDeflateLength: this.options.min_deflate_length
});
frame.pack(this.options.deflate, (function(_this) {
return function(err, bin) {
if (err) {
if (cb) {
cb(err);
}
return;
}
_this.socket.write(bin);
if (cb) {
return cb(null);
}
};
})(this));
};
Message.prototype.ping = function(cb) {
this.write('', 'ping', false, cb);
};
Message.prototype.pong = function(cb) {
this.write('', 'pong', false, cb);
};
Message.prototype["continue"] = function(cb) {
this.write('', 'continue', false, cb);
};
Message.prototype.writeRaw = function(bin) {
return this.socket.write(bin);
};
Message.prototype.end = function(data, opcode, mask) {
if (data != null) {
this.write(data, opcode, mask, (function(_this) {
return function() {
return _this.close();
};
})(this));
} else {
this.close();
}
};
Message.prototype.close = function() {
var closed;
closed = false;
return this.write('', 'close', false, (function(_this) {
return function() {
var timer;
_this.socket.on('close', function(err) {
clearTimeout(timer);
closed = true;
return _this.emit('closed', err);
});
return timer = setTimeout(function() {
if (closed) {
return;
}
return _this.socket.end();
}, _this.options.close_timeout);
};
})(this));
};
Message.prototype.onFrame = function(frame) {
switch (frame.opcode) {
case 'text':
this.emit('message', frame.data.toString(), this);
break;
case 'binary':
this.emit('message', frame.data, this);
break;
case 'ping':
this.emit('ping');
break;
case 'pong':
this.emit('pong');
break;
case 'close':
this.socket.end();
this.emit('close');
break;
case 'continue':
this.emit('continue');
}
};
Message.prototype.reset = function(options) {
this.options = os(this.options, options);
return this.__QWS_CB = options.cb;
};
Message.prototype.errorHandle = function(msg) {
if (msg) {
this.write(msg);
}
return this.close();
};
return Message;
})(EventEmitter);
exports.Message = Message;