Various code simplifications and fixes.
This commit is contained in:
parent
719b63ee02
commit
13f36b3f79
@ -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]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
src/index.js
29
src/index.js
@ -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)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
24
src/xo.js
24
src/xo.js
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user