Comparing version 0.2.1 to 0.3.0
@@ -7,116 +7,81 @@ /** | ||
*/ | ||
EventEmitter = require('events').EventEmitter; | ||
module.exports = (function(Super, assertTransport) { | ||
/** | ||
* Client | ||
* @param {WebSocket} socket | ||
* @param {Function} inbound | ||
* @param {Function} oubbound | ||
*/ | ||
function Client(socket, inbound, oubbound) { | ||
this._socket = socket; | ||
if (typeof inbound === 'function') { | ||
this.in = inbound; | ||
} | ||
if (typeof oubbound === 'function') { | ||
this.out = oubbound; | ||
} | ||
/** | ||
* Client | ||
* @param {Transport} transport | ||
* @param {Function} inbound | ||
* @param {Function} outbound | ||
* @api public | ||
*/ | ||
function Client(transport, inbound, outbound) { | ||
Super.call(this); | ||
this.transport = assertTransport(transport); | ||
this.in = inbound || function(data, callback) { | ||
callback('data', data); | ||
}; | ||
this.out = outbound || function(data, callback) { | ||
callback(data); | ||
}; | ||
bindEvents.call(this); | ||
}; | ||
var self = this; | ||
transport.on('data', function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
args.push(function(event, data) { | ||
self.emit(event, data); | ||
}); | ||
self.in.apply(self, args); | ||
}); | ||
}; | ||
/** | ||
* Inherit from EventEmitter.prototype | ||
*/ | ||
Client.prototype = Object.create(EventEmitter.prototype); | ||
/** | ||
* Inherit Super.prototype | ||
*/ | ||
Client.prototype = Object.create(Super.prototype); | ||
/** | ||
* Handle messages sent to the server | ||
* @param {Mixed} data | ||
* @param {Function} callback | ||
* @return {Client} | ||
*/ | ||
Client.prototype.in = function(data, callback) { | ||
callback('message', data); | ||
return this; | ||
}; | ||
/** | ||
* Handle messages sent from the server | ||
* @param {Mixed} data | ||
* @param {Function} callback | ||
* @return {Client} | ||
*/ | ||
Client.prototype.out = function(data, callback) { | ||
callback(data); | ||
return this; | ||
}; | ||
/** | ||
* Send a message to the client | ||
* @param {Mixed} arg1 | ||
* @param {Mixed} arg2 | ||
* @param {Mixed} [...] | ||
* @return {Client} | ||
*/ | ||
Client.prototype.send = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
args.unshift('send'); | ||
this.emit.apply(this, args); | ||
return this; | ||
}; | ||
/** | ||
* Bind client events | ||
*/ | ||
function bindEvents() { | ||
var self = this; | ||
this._socket.on('message', function(data) { | ||
self.in(data, function() { | ||
self.emit.apply(self, arguments); | ||
}); | ||
}); | ||
this.on('send', function() { | ||
/** | ||
* Write to clients | ||
* @return {Client} | ||
* @api public | ||
*/ | ||
Client.prototype.write = function() { | ||
var self = this; | ||
var args = Array.prototype.slice.call(arguments); | ||
args.push(function(data) { | ||
self._socket.send(data); | ||
self.transport.write(data); | ||
}); | ||
self.out.apply(self, args); | ||
}); | ||
this.out.apply(null, args) | ||
return this; | ||
}; | ||
this._socket.on('close', function() { | ||
self.emit('close'); | ||
}); | ||
}; | ||
/** | ||
* @param {Mixed} client | ||
* @return {Boolean} | ||
* @api public | ||
*/ | ||
function isClient(client) { | ||
return client instanceof Client; | ||
}; | ||
/** | ||
* Is client | ||
* @param {Mixed} client | ||
* @return {Boolean} | ||
*/ | ||
function isClient(client) { | ||
return client instanceof Client; | ||
}; | ||
/** | ||
* @param {Mixed} client | ||
* @return {Client} | ||
* @api public | ||
*/ | ||
function assertClient(client) { | ||
if (!isClient(client)) { | ||
throw new Error('Invalid client.'); | ||
} | ||
return client; | ||
}; | ||
/** | ||
* Assert client | ||
* @param {Mixed} client | ||
* @return {Client} | ||
*/ | ||
function assertClient(client) { | ||
if (!isClient(client)) { | ||
throw new Error('Invalid client.'); | ||
} | ||
return client; | ||
}; | ||
/** | ||
* Exports | ||
*/ | ||
return { | ||
Client: Client, | ||
is: isClient, | ||
assert: assertClient | ||
}; | ||
/** | ||
* Export | ||
*/ | ||
module.exports = { | ||
Client: Client, | ||
isClient: isClient, | ||
assertClient: assertClient | ||
}; | ||
})(require('events').EventEmitter, require('./transports/transport').assert); |
143
lib/pool.js
@@ -7,94 +7,65 @@ /** | ||
*/ | ||
EventEmitter = require('events').EventEmitter; | ||
assertClient = require('./client').assertClient; | ||
module.exports = (function(Super, assertClient) { | ||
/** | ||
* Pool | ||
* @param {String} name | ||
*/ | ||
function Pool(name) { | ||
this.clients = []; | ||
this.name = name; | ||
}; | ||
/** | ||
* Pool | ||
* @param {Object} options | ||
* @api public | ||
*/ | ||
function Pool(name) { | ||
this.name = name; | ||
this.clients = []; | ||
Super.call(this); | ||
}; | ||
/** | ||
* Inherit from EventEmitter.prototype | ||
*/ | ||
Pool.prototype = Object.create(EventEmitter.prototype); | ||
/** | ||
* Inherit Super.prototype | ||
*/ | ||
Pool.prototype = Object.create(Super.prototype); | ||
/** | ||
* Attach a client | ||
* @param {Client} client | ||
* @return {Pool} | ||
*/ | ||
Pool.prototype.attach = function(client) { | ||
var self = this; | ||
this.clients.push(assertClient(client)); | ||
client.on('close', function() { | ||
self.detach(client); | ||
}); | ||
/** | ||
* Attach a client | ||
* @param {Client} client | ||
* @return {Pool} | ||
* @api public | ||
*/ | ||
Pool.prototype.attach = function(client) { | ||
this.detach(client); | ||
this.clients.push(assertClient(client)); | ||
return this; | ||
}; | ||
return this; | ||
}; | ||
/** | ||
* Detach a client | ||
* @param {Client} client | ||
* @return {Pool} | ||
* @api public | ||
*/ | ||
Pool.prototype.detach = function(client) { | ||
var index = this.clients.indexOf(assertClient(client)); | ||
if (-1 < index) { | ||
this.clients.splice(index, 1); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* Detach a client | ||
* @param {Client} client | ||
* @return {Pool} | ||
*/ | ||
Pool.prototype.detach = function(client) { | ||
var i = this.clients.indexOf(assertClient(client)); | ||
if (-1 < i) { | ||
this.clients.splice(i, 1); | ||
} | ||
/** | ||
* Write to clients | ||
* @return {Pool} | ||
* @api public | ||
*/ | ||
Pool.prototype.write = function(data) { | ||
this.clients.forEach(function(client) { | ||
client.write(data); | ||
}); | ||
return this; | ||
}; | ||
return this; | ||
}; | ||
/** | ||
* Exports | ||
*/ | ||
return { | ||
Pool: Pool | ||
}; | ||
/** | ||
* Send a message to the pool | ||
* @param {Mixed} arg1 | ||
* @param {Mixed} arg2 | ||
* @param {Mixed} [...] | ||
* @return {Pool} | ||
*/ | ||
Pool.prototype.send = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
this.clients.forEach(function(client) { | ||
client.send.apply(client, args); | ||
}); | ||
args.unshift('send'); | ||
this.emit.apply(this, args); | ||
return this; | ||
}; | ||
/** | ||
* Is pool | ||
* @param {Mixed} pool | ||
* @return {Boolean} | ||
*/ | ||
function isPool(pool) { | ||
return pool instanceof Pool; | ||
}; | ||
/** | ||
* Assert pool | ||
* @param {Mixed} pool | ||
* @return {Pool} | ||
*/ | ||
function assertPool(pool) { | ||
if (!isPool(pool)) { | ||
throw new Error('Invalid pool.'); | ||
} | ||
return pool; | ||
}; | ||
/** | ||
* Export | ||
*/ | ||
module.exports = { | ||
Pool: Pool, | ||
isPool: isPool, | ||
assertPool: assertPool | ||
}; | ||
})(require('events').EventEmitter, require('./client').assert); |
@@ -7,140 +7,102 @@ /** | ||
*/ | ||
EventEmitter = require('events').EventEmitter; | ||
Client = require('./client').Client; | ||
Pool = require('./pool').Pool; | ||
module.exports = (function(Super, Pool, Client, assertTransport) { | ||
/** | ||
* Server | ||
* @param {WebSocketServer} server | ||
* @param {Function} inbound | ||
* @param {Function} outbound | ||
* @param {Function} pooling | ||
*/ | ||
function Server(server, inbound, outbound, pooling) { | ||
var self = this; | ||
this._server = server; | ||
this._inbound = inbound; | ||
this._outbound = outbound; | ||
this._pooling = pooling; | ||
this.pools = {}; | ||
/** | ||
* Server | ||
* @param {Array} transports | ||
* @api public | ||
*/ | ||
function Server(transports) { | ||
Super.call(this); | ||
this._transports = transports; | ||
this.pools = {}; | ||
this._pool = function(transport) { | ||
return transport.identify(); | ||
}; | ||
if (typeof this._pooling !== 'function') { | ||
this._pooling = function(client, callback) { | ||
callback(client._socket.upgradeReq.url); | ||
} | ||
} | ||
var self = this; | ||
this._transports.forEach(function(transport) { | ||
assertTransport(transport).on('connection', function(stream) { | ||
var client = new Client(stream, self._in, self._out); | ||
var pool = self._pool(stream); | ||
bindEvents.call(this); | ||
}; | ||
if (null == self.pools[pool]) { | ||
self.pools[pool] = new Pool(pool); | ||
} | ||
/** | ||
* Inherit from EventEmitter.prototype | ||
*/ | ||
Server.prototype = Object.create(EventEmitter.prototype); | ||
self.pools[pool].attach(client); | ||
self.emit('connection', client, self.pools[pool]); | ||
}); | ||
}); | ||
}; | ||
/** | ||
* Close the server | ||
*/ | ||
Server.prototype.close = function() { | ||
this._server.close(); | ||
} | ||
/** | ||
* Inherit Super.prototype | ||
*/ | ||
Server.prototype = Object.create(Super.prototype); | ||
/** | ||
* Set the client inbound message handler | ||
* @param {Function} callback | ||
* @return {Server} | ||
*/ | ||
Server.prototype.in = function(callback) { | ||
this._inbound = callback; | ||
return this; | ||
}; | ||
/** | ||
* Listen to network | ||
* @param {Mixed} spec | ||
* @return {Server} | ||
*/ | ||
Server.prototype.listen = function(spec) { | ||
this._transports.forEach(function(transport) { | ||
transport.listen(spec); | ||
}); | ||
return this; | ||
}; | ||
/** | ||
* Set the client outbound message handler | ||
* @param {Function} callback | ||
* @return {Server} | ||
*/ | ||
Server.prototype.out = function(callback) { | ||
this._outbound = callback; | ||
return this; | ||
}; | ||
/** | ||
* Set the inbound message handler | ||
* @param {Function} callback | ||
* @return {Server} | ||
*/ | ||
Server.prototype.in = function(callback) { | ||
this._in = callback; | ||
return this; | ||
}; | ||
/** | ||
* Send a message to server | ||
* @param {Mixed} arg1 | ||
* @param {Mixed} arg2 | ||
* @param {Mixed} [...] | ||
* @return {Server} | ||
*/ | ||
Server.prototype.send = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
for (var i in this.pools) { | ||
this.pools[i].send.apply(this.pools[i], args); | ||
} | ||
args.unshift('send'); | ||
this.emit.apply(this, args); | ||
/** | ||
* Set the outbound message handler | ||
* @param {Function} callback | ||
* @return {Server} | ||
*/ | ||
Server.prototype.out = function(callback) { | ||
this._out = callback; | ||
return this; | ||
}; | ||
return this; | ||
}; | ||
/** | ||
* Set the client pooling handler | ||
* @param {Function} callback | ||
* @return {Server} | ||
*/ | ||
Server.prototype.pool = function(callback) { | ||
this._pool = callback; | ||
return this; | ||
}; | ||
/** | ||
* Set the client pooling handler | ||
* @param {Function} callback | ||
* @return {Server} | ||
*/ | ||
Server.prototype.with = function(callback) { | ||
this._pooling = callback; | ||
return this; | ||
}; | ||
/** | ||
* Write to clients | ||
* @return {Server} | ||
* @api public | ||
*/ | ||
Server.prototype.write = function(data) { | ||
for(var i in this.pools) { | ||
this.pools[i].write(data); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* Bind server events | ||
*/ | ||
function bindEvents() { | ||
var self = this; | ||
this._server.on('connection', function(socket) { | ||
var client = new Client(socket, self._inbound, self._outbound); | ||
/** | ||
* Exports | ||
*/ | ||
return { | ||
Server: Server | ||
}; | ||
self._pooling(client, function(name) { | ||
if (null != self.pools[name]) { | ||
var pool = self.pools[name]; | ||
} else { | ||
var pool = new Pool(name); | ||
self.pools[name] = pool; | ||
} | ||
pool.attach(client); | ||
self.emit('connection', client, pool); | ||
}); | ||
}); | ||
}; | ||
/** | ||
* Is server | ||
* @param {Mixed} server | ||
* @return {Boolean} | ||
*/ | ||
function isServer(server) { | ||
return server instanceof Server; | ||
}; | ||
/** | ||
* Assert server | ||
* @param {Mixed} server | ||
* @return {Server} | ||
*/ | ||
function assertServer(server) { | ||
if (!isServer(server)) { | ||
throw new Error('Invalid server.'); | ||
} | ||
return server; | ||
}; | ||
/** | ||
* Export | ||
*/ | ||
module.exports = { | ||
Server: Server, | ||
isServer: isServer, | ||
assertServer: assertServer | ||
}; | ||
})(require('events').EventEmitter, | ||
require('./pool').Pool, | ||
require('./client').Client, | ||
require('./transports/transport').assert); |
{ | ||
"name": "wesley", | ||
"description": "Protocol compliant web socket server with some awesome extras.", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"homepage": "http://wesleyjs.org", | ||
@@ -22,2 +22,3 @@ | ||
"main": "./lib/wesley.js", | ||
"bin": { | ||
@@ -39,5 +40,4 @@ "wesley": "./bin/wesley" | ||
"chai": "~1.5.0", | ||
"mocha": "~1.8.1", | ||
"sinon": "~1.6.0" | ||
"mocha": "~1.8.1" | ||
} | ||
} |
# Wesley # | ||
**Version:** *0.2.1*<br/> | ||
**Version:** *0.3.0*<br/> | ||
**Master build:** [![Master branch build status][travis-master]][travis] | ||
@@ -19,7 +19,7 @@ | ||
server.on('connection', function (client) { | ||
server.on('connection', function(client) { | ||
// Relay a message to all clients on the server | ||
client.on('message', function (message) { | ||
server.send(message); | ||
// Relay data to all clients on the server | ||
client.on('data', function(data) { | ||
server.write(data); | ||
}); | ||
@@ -36,7 +36,7 @@ | ||
server.on('connection', function (client, pool) { | ||
server.on('connection', function(client, pool) { | ||
// Relay a message to the current pool of clients | ||
client.on('message', function (message) { | ||
pool.send(message); | ||
// Relay data to the current pool of clients | ||
client.on('data', function(data) { | ||
pool.write(data); | ||
}); | ||
@@ -60,10 +60,8 @@ | ||
}; | ||
var server = require('wesley') | ||
.listen(3000) | ||
.with(pooling); | ||
var server = require('wesley').listen(3000).pool(pooling); | ||
server.on('connection', function (client, pool) { | ||
server.on('connection', function(client, pool) { | ||
// handle the client | ||
client.send('You\'ve just joined the ' + pool.name + ' pool.'); | ||
// Handle the client | ||
client.write('You\'ve just joined the ' + pool.name + ' pool.'); | ||
@@ -75,16 +73,14 @@ }); | ||
### Inbound messages ### | ||
By default, a Wesley client will emit `message` for every message sent from the client. | ||
By default, a Wesley client will emit `data` for every message sent from the client. | ||
You can entirely replace this behaviour at your leisure. | ||
```js | ||
var inbound = function(message, callback) { | ||
callback('echo', message); | ||
var inbound = function(data, callback) { | ||
callback('message', data); | ||
}; | ||
var server = require('wesley') | ||
.listen(3000) | ||
.in(inbound); | ||
var server = require('wesley').listen(3000).in(inbound); | ||
server.on('connection', function (client) { | ||
server.on('connection', function(client) { | ||
client.on('echo', function(message) { | ||
// handle the message | ||
client.on('message', function(message) { | ||
// Handle the message | ||
}); | ||
@@ -99,12 +95,10 @@ | ||
var data = JSON.parse(json); | ||
callback('message', data); | ||
callback('data', data); | ||
}; | ||
var server = require('wesley') | ||
.listen(3000) | ||
.in(inbound); | ||
var server = require('wesley').listen(3000).in(inbound); | ||
server.on('connection', function (client) { | ||
server.on('connection', function(client) { | ||
client.on('message', function(data) { | ||
// handle the data | ||
client.on('data', function(data) { | ||
// Handle the data | ||
}); | ||
@@ -123,9 +117,8 @@ | ||
}; | ||
var server = require('wesley') | ||
.listen(3000) | ||
.out(outbound); | ||
var server = require('wesley').listen(3000).out(outbound); | ||
server.on('connection', function (client) { | ||
server.on('connection', function(client) { | ||
client.send('message', 'Derp.'); | ||
// Send data to the client | ||
client.write('message', 'Derp.'); | ||
@@ -136,3 +129,26 @@ }); | ||
### Command line interface ### | ||
### Transports ### | ||
As Wesley is a web socket server, it uses a socket transport by default. | ||
You can create custom transports by extending `wesley.Transport`. | ||
It is the job of the transport to proxy events listened to by the client | ||
or server. Please see the documentation for more detail (Coming soon). | ||
Once you have a client, using it is simple. | ||
```js | ||
var wesley = require('wesley'); | ||
var server = new wesley.Server([ | ||
// An array of transports | ||
new CustomTransport() | ||
]); | ||
server.on('connection', function(client, pool) { | ||
// Client wraps the the transport the connection came through | ||
client.write('Derp.'); | ||
}); | ||
``` | ||
### Command line client ### | ||
I can tell you're super excited to start working on your web socket server. | ||
@@ -139,0 +155,0 @@ One thing you may find useful is a client to start interacting with. |
@@ -1,24 +0,16 @@ | ||
var ws = require('ws'); | ||
var Server = require('./lib/server').Server; | ||
var Client = require('./lib/client').Client; | ||
var Pool = require('./lib/pool').Pool; | ||
var server = new Server(new ws.Server({port:1234})); | ||
(function(wesley) { | ||
server.on('connection', function(client, pool) { | ||
// console.log(socket); | ||
// console.log(client); | ||
// console.log(pool); | ||
console.log('Joined: ' + pool.name); | ||
var server = wesley.listen(3000); | ||
client.on('message', function(data) { | ||
pool.send(data); | ||
client.send(data); | ||
console.log(data); | ||
server.on('connection', function(client, pool) { | ||
client.on('data', function(data) { | ||
console.log(data); | ||
client.write(data); | ||
pool.write(data); | ||
server.write(data); | ||
}); | ||
}); | ||
client.on('close', function() { | ||
console.log('disconnect'); | ||
console.log(pool); | ||
console.log(pool.clients.length); | ||
}); | ||
}); | ||
})(require('./lib/wesley')); |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
18949
2
14
464
194
1