UNPKG

qws

Version:

An HTML5 Web Sockets Server Module

196 lines (176 loc) 4.87 kB
// 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;