Comparing version 0.2.2 to 0.2.3
{ | ||
"name": "koa-ws", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"keywords": [ | ||
@@ -5,0 +5,0 @@ "koa", |
@@ -30,3 +30,5 @@ [![Build Status](https://secure.travis-ci.org/mekwall/koa-ws.png)](http://travis-ci.org/mekwall/koa-ws) [![Coverage Status](https://img.shields.io/coveralls/mekwall/koa-ws.svg)](https://coveralls.io/r/mekwall/koa-ws) [![Dependency Status](https://david-dm.org/mekwall/koa-ws.png)](https://david-dm.org/mekwall/koa-ws) | ||
serveClientFile: true, | ||
clientFilePath: '/koaws.js' | ||
clientFilePath: '/koaws.js', | ||
heartbeat: true, | ||
heartbeatInterval: 5000 | ||
}; | ||
@@ -66,2 +68,8 @@ | ||
##### heartbeat (default: true) | ||
If server/client should send hearbeats to eachother | ||
##### heartbeatInterval (default: 5000) | ||
How often the heartbeat should be sent | ||
##### serveClientFile (default: true) | ||
@@ -68,0 +76,0 @@ Will try and serve the client library file when `this.path` matches the `clientFilePath` option. |
@@ -11,4 +11,4 @@ (function(){ | ||
// Request object | ||
var Request = require('./request'); | ||
// Protocol | ||
var protocol = require('./jsonrpc'); | ||
@@ -58,2 +58,8 @@ // Debug output | ||
// Options container | ||
this._options = {}; | ||
// Session container | ||
this._session = null; | ||
// On WebSocket open | ||
@@ -67,2 +73,13 @@ this.on('open', this.onOpen); | ||
this.on('message', this.onMessage); | ||
var _this = this; | ||
// Listen for options | ||
this.register('options', function () { | ||
_this._options = this.params; | ||
}); | ||
// Listen for session | ||
this.register('session', function () { | ||
_this._session = this.params; | ||
}); | ||
}; | ||
@@ -89,39 +106,4 @@ | ||
Client.prototype.onMessage = function (e) { | ||
var payload = JSON.parse(e.data || e); | ||
if (payload.method) { | ||
var request = new Request(this.socket, payload); | ||
if (typeof this._methods[payload.method] === 'undefined') { | ||
debug('← (%s) Missing handler', payload.method); | ||
} else if (payload.error) { | ||
debug('← (%s) Error %s: %o', payload.method, payload.error.code, payload.error.message); | ||
this._methods[payload.method].apply( | ||
request, | ||
[payload.error, payload.params] | ||
); | ||
} else { | ||
debug('← (%s) %s: %o', payload.id, payload.method, payload.params); | ||
this._methods[payload.method].apply( | ||
request, | ||
[null, payload.params] | ||
); | ||
} | ||
} else { | ||
if (payload.error && payload.id && this._awaitingResults[payload.id]) { | ||
debug('← (%s) Error %s: %o', payload.id, payload.error.code, payload.error.message); | ||
this._awaitingResults[payload.id].apply( | ||
this, | ||
[payload.error] | ||
); | ||
} else if (payload.error) { | ||
debug('← Error %s: %o', payload.error.code, payload.error.message); | ||
} else if (payload.id && this._awaitingResults[payload.id]) { | ||
debug('← (%s) %o', payload.id, payload.result); | ||
this._awaitingResults[payload.id].apply( | ||
this, | ||
[null, payload.result] | ||
); | ||
} | ||
} | ||
Client.prototype.onMessage = function (data) { | ||
protocol.apply(this, [debug, this.socket, data]); | ||
}; | ||
@@ -152,10 +134,14 @@ | ||
// Register a client-side method | ||
Client.prototype.register = function (method, handler) { | ||
if (typeof handler === 'object') { | ||
for (var name in handler) { | ||
debug('Registering method: %s:%s', method, name); | ||
this._methods[method + ':' + name] = handler[name]; | ||
Client.prototype.register = function (method, handler, expose) { | ||
if (typeof method === 'object') { | ||
for (var m in method) { | ||
this.register(m, method[m]); | ||
} | ||
} else { | ||
} else if (typeof handler === 'object') { | ||
for (var m in handler) { | ||
this.register(method + ':' + m, handler[m]); | ||
} | ||
} else if (typeof method === 'string') { | ||
debug('Registering method: %s', method); | ||
handler.expose = expose || false; | ||
this._methods[method] = handler; | ||
@@ -162,0 +148,0 @@ } |
@@ -14,2 +14,4 @@ var fs = require('fs'); | ||
clientFilePath: '/koaws.js', | ||
heartbeat: true, | ||
heartbeatInterval: 5000 | ||
}; | ||
@@ -16,0 +18,0 @@ // Override with passed options |
@@ -8,2 +8,5 @@ var co = require('co'); | ||
// Protocol | ||
var protocol = require('./jsonrpc'); | ||
// Debug output | ||
@@ -21,2 +24,5 @@ var debug = require('debug')('koa-ws:server'); | ||
// Container for options | ||
this._options = options || {}; | ||
// Container for methods | ||
@@ -141,63 +147,20 @@ this._methods = {}; | ||
socket.on('message', function (message) { | ||
try { | ||
var payload = JSON.parse(message); | ||
} catch (e) { | ||
debug('Parse error: %s', e.stack); | ||
socket.error(-32700, 'Parse error'); | ||
return; | ||
} | ||
protocol.apply(this, [debug, socket, message]); | ||
}.bind(this)); | ||
var request = new Request(socket, payload); | ||
// Send options | ||
socket.method('options', this._options); | ||
if (!payload.jsonrpc && payload.jsonrpc !== '2.0') { | ||
debug('Wrong protocol: %s', payload.jsonrpc); | ||
socket.error.apply(request, [-32600, 'Invalid request']); | ||
return; | ||
} | ||
// Send initial thump | ||
if (this._options.heartbeat) { | ||
socket.send('--thump--'); | ||
} | ||
if (!payload.method && (!payload.result && !payload.id)) { | ||
debug('Missing method: %o', payload); | ||
socket.error.apply(request, [-32600, 'Invalid request']); | ||
return; | ||
} | ||
if (typeof payload.params !== 'undefined' && typeof payload.params !== 'object' && !Array.isArray(payload.params)) { | ||
debug('Invalid params: %o', payload.params); | ||
socket.error.apply(request, [-32602, 'Invalid params']); | ||
return; | ||
} | ||
if (payload.id && payload.error) { | ||
debug('← (%s) Error %s: %o', payload.id, payload.error.code, payload.error.message); | ||
if (typeof this._awaitingResults[payload.id] === 'function') { | ||
this._awaitingResults[payload.id].apply(this, [payload.error]); | ||
} | ||
} else if (payload.id && payload.result) { | ||
debug('← (%s) Result: %o', payload.id, payload.result); | ||
if (typeof this._awaitingResults[payload.id] === 'function') { | ||
this._awaitingResults[payload.id].apply(this, [null, payload.result]); | ||
} | ||
} else { | ||
debug('← (%s) %s: %o', payload.id, payload.method, payload.params); | ||
if (typeof methods[payload.method] === 'function') { | ||
try { | ||
methods[payload.method].apply(request); | ||
} catch (e) { | ||
debug('Internal error: %s', e.stack); | ||
socket.error.apply(request, [-32603, 'Internal error']); | ||
} | ||
} else { | ||
debug('Method not found: %s', payload.method, payload.params); | ||
socket.error.apply(request, [-32601, 'Method not found']); | ||
} | ||
} | ||
}.bind(this)); | ||
// Let's try and connect the socket to session | ||
var sessionId = cookieHelper.get(socket, 'koa.sid', this.app.keys); | ||
if (sessionId) { | ||
if (typeof this.sockets[sessionId] === 'undefined') { | ||
this.sockets[sessionId] = []; | ||
if (typeof this._sockets[sessionId] === 'undefined') { | ||
this._sockets[sessionId] = []; | ||
} | ||
this.sockets[sessionId].push(socket); | ||
this._sockets[sessionId].push(socket); | ||
@@ -204,0 +167,0 @@ if (this.app.sessionStore) { |
@@ -34,3 +34,6 @@ var fs = require('fs'); | ||
var middleware = require('../src/middleware'); | ||
app.use(middleware(app)); | ||
app.use(middleware(app, { | ||
heartbeatInterval: 500, | ||
heartbeat: false | ||
})); | ||
expect(app).to.have.property('ws'); | ||
@@ -178,2 +181,11 @@ }); | ||
it('expect heartbeat response from client', function (done) { | ||
socket.once('message', function (message) { | ||
if (message === '--thump--') { | ||
done(); | ||
} | ||
}); | ||
socket.send('--thump--'); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
28708
15
657
111