Various code simplifications and fixes.

This commit is contained in:
Julien Fontanet 2015-04-28 15:47:26 +02:00
parent 719b63ee02
commit 13f36b3f79
3 changed files with 36 additions and 48 deletions

View File

@ -2,43 +2,28 @@ import {EventEmitter} from 'events'
// ===================================================================
const has = (function () {
return (val, prop) => hasOwnProperty.call(val, prop)
})(Object.hasOwnProperty)
const noop = () => {}
// const noop = () => {}
// ===================================================================
export default class Connection extends EventEmitter {
constructor ({close, notify}) {
constructor () {
super()
this._close = close
this.data = Object.create(null)
this.notify = notify
this._data = Object.create(null)
}
// Close the connection.
close () {
// Prevent errors when the connection is closed more than once.
this.close = noop
this._close()
// this.close = noop
this.emit('close')
// Releases values AMAP to ease the garbage collecting.
for (let key in this) {
if (key !== 'close' && has(this, key)) {
delete this[key]
}
}
}
// Gets the value for this key.
get (key, defaultValue) {
const {data} = this
const {_data: data} = this
if (key in data) {
return data[key]
@ -53,15 +38,15 @@ export default class Connection extends EventEmitter {
// Checks whether there is a value for this key.
has (key) {
return key in this.data
return key in this._data
}
// Sets the value for this key.
set (key, value) {
this.data[key] = value
this._data[key] = value
}
unset (key) {
delete this.data[key]
delete this._data[key]
}
}

View File

@ -206,33 +206,32 @@ const setUpApi = (webServer, xo) => {
path: '/api/'
})
webSocketServer.on('connection', connection => {
webSocketServer.on('connection', socket => {
debug('+ WebSocket connection')
let xoConnection
// Create the abstract XO object for this connection.
const connection = xo.createUserConnection()
connection.once('close', () => {
socket.close()
})
// Create the JSON-RPC server for this connection.
const jsonRpc = createJsonRpcServer(message => {
if (message.type === 'request') {
return api.call(xoConnection, message.method, message.params)
return api.call(connection, message.method, message.params)
}
})
// Create the abstract XO object for this connection.
xoConnection = xo.createUserConnection({
close: bind(connection.close, connection),
notify: bind(jsonRpc.notify, jsonRpc)
})
connection.notify = bind(jsonRpc.notify, jsonRpc)
// Close the XO connection with this WebSocket.
connection.once('close', () => {
socket.once('close', () => {
debug('- WebSocket connection')
xoConnection.close()
connection.close()
})
// Connect the WebSocket to the JSON-RPC server.
connection.on('message', message => {
socket.on('message', message => {
jsonRpc.write(message)
})
@ -242,7 +241,11 @@ const setUpApi = (webServer, xo) => {
}
}
jsonRpc.on('data', data => {
connection.send(JSON.stringify(data), onSend)
// The socket may have been closed during the API method
// execution.
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify(data), onSend)
}
})
})
}

View File

@ -123,7 +123,9 @@ export default class Xo extends EventEmitter {
let exited = {}
let dispatcherRegistered = false
const dispatcher = () => {
const dispatcher = Bluebird.method(() => {
dispatcherRegistered = false
const {connections} = this
if (!isEmpty(entered)) {
@ -131,6 +133,7 @@ export default class Xo extends EventEmitter {
type: 'enter',
items: pluck(entered, 'val')
}
entered = {}
for (let id in connections) {
const connection = connections[id]
@ -139,15 +142,14 @@ export default class Xo extends EventEmitter {
connection.notify('all', enterParams)
}
}
entered = {}
}
if (!isEmpty(entered)) {
if (!isEmpty(exited)) {
const exitParams = {
type: 'exit',
items: pluck(exited, 'val')
}
exited = {}
for (let id in connections) {
const connection = connections[id]
@ -156,10 +158,8 @@ export default class Xo extends EventEmitter {
connection.notify('all', exitParams)
}
}
exited = {}
}
}
})
this._xobjs.on('any', (event, items) => {
if (!dispatcherRegistered) {
@ -326,16 +326,16 @@ export default class Xo extends EventEmitter {
// -----------------------------------------------------------------
createUserConnection (opts) {
createUserConnection () {
const {connections} = this
const connection = new Connection(opts)
const connection = new Connection()
const id = connection.id = this._nextConId++
connection.on('close', () => {
connections[id]
})
connections[id] = connection
connection.on('close', () => {
delete connections[id]
})
return connection
}