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 () { // const noop = () => {}
return (val, prop) => hasOwnProperty.call(val, prop)
})(Object.hasOwnProperty)
const noop = () => {}
// =================================================================== // ===================================================================
export default class Connection extends EventEmitter { export default class Connection extends EventEmitter {
constructor ({close, notify}) { constructor () {
super() super()
this._close = close this._data = Object.create(null)
this.data = Object.create(null)
this.notify = notify
} }
// Close the connection. // Close the connection.
close () { close () {
// Prevent errors when the connection is closed more than once. // Prevent errors when the connection is closed more than once.
this.close = noop // this.close = noop
this._close()
this.emit('close') 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. // Gets the value for this key.
get (key, defaultValue) { get (key, defaultValue) {
const {data} = this const {_data: data} = this
if (key in data) { if (key in data) {
return data[key] return data[key]
@ -53,15 +38,15 @@ export default class Connection extends EventEmitter {
// Checks whether there is a value for this key. // Checks whether there is a value for this key.
has (key) { has (key) {
return key in this.data return key in this._data
} }
// Sets the value for this key. // Sets the value for this key.
set (key, value) { set (key, value) {
this.data[key] = value this._data[key] = value
} }
unset (key) { unset (key) {
delete this.data[key] delete this._data[key]
} }
} }

View File

@ -206,33 +206,32 @@ const setUpApi = (webServer, xo) => {
path: '/api/' path: '/api/'
}) })
webSocketServer.on('connection', connection => { webSocketServer.on('connection', socket => {
debug('+ WebSocket connection') 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. // Create the JSON-RPC server for this connection.
const jsonRpc = createJsonRpcServer(message => { const jsonRpc = createJsonRpcServer(message => {
if (message.type === 'request') { if (message.type === 'request') {
return api.call(xoConnection, message.method, message.params) return api.call(connection, message.method, message.params)
} }
}) })
connection.notify = bind(jsonRpc.notify, jsonRpc)
// Create the abstract XO object for this connection.
xoConnection = xo.createUserConnection({
close: bind(connection.close, connection),
notify: bind(jsonRpc.notify, jsonRpc)
})
// Close the XO connection with this WebSocket. // Close the XO connection with this WebSocket.
connection.once('close', () => { socket.once('close', () => {
debug('- WebSocket connection') debug('- WebSocket connection')
xoConnection.close() connection.close()
}) })
// Connect the WebSocket to the JSON-RPC server. // Connect the WebSocket to the JSON-RPC server.
connection.on('message', message => { socket.on('message', message => {
jsonRpc.write(message) jsonRpc.write(message)
}) })
@ -242,7 +241,11 @@ const setUpApi = (webServer, xo) => {
} }
} }
jsonRpc.on('data', data => { 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 exited = {}
let dispatcherRegistered = false let dispatcherRegistered = false
const dispatcher = () => { const dispatcher = Bluebird.method(() => {
dispatcherRegistered = false
const {connections} = this const {connections} = this
if (!isEmpty(entered)) { if (!isEmpty(entered)) {
@ -131,6 +133,7 @@ export default class Xo extends EventEmitter {
type: 'enter', type: 'enter',
items: pluck(entered, 'val') items: pluck(entered, 'val')
} }
entered = {}
for (let id in connections) { for (let id in connections) {
const connection = connections[id] const connection = connections[id]
@ -139,15 +142,14 @@ export default class Xo extends EventEmitter {
connection.notify('all', enterParams) connection.notify('all', enterParams)
} }
} }
entered = {}
} }
if (!isEmpty(entered)) { if (!isEmpty(exited)) {
const exitParams = { const exitParams = {
type: 'exit', type: 'exit',
items: pluck(exited, 'val') items: pluck(exited, 'val')
} }
exited = {}
for (let id in connections) { for (let id in connections) {
const connection = connections[id] const connection = connections[id]
@ -156,10 +158,8 @@ export default class Xo extends EventEmitter {
connection.notify('all', exitParams) connection.notify('all', exitParams)
} }
} }
exited = {}
} }
} })
this._xobjs.on('any', (event, items) => { this._xobjs.on('any', (event, items) => {
if (!dispatcherRegistered) { if (!dispatcherRegistered) {
@ -326,16 +326,16 @@ export default class Xo extends EventEmitter {
// ----------------------------------------------------------------- // -----------------------------------------------------------------
createUserConnection (opts) { createUserConnection () {
const {connections} = this const {connections} = this
const connection = new Connection(opts) const connection = new Connection()
const id = connection.id = this._nextConId++ const id = connection.id = this._nextConId++
connection.on('close', () => {
connections[id]
})
connections[id] = connection connections[id] = connection
connection.on('close', () => {
delete connections[id]
})
return connection return connection
} }