UNPKG

fox-wamp

Version:

Web Application Message Router/Server WAMP/MQTT

146 lines (121 loc) 3.44 kB
'use strict' const { EventEmitter } = require('events') const { REALM_CREATED, SESSION_TX, SESSION_RX, SESSION_ALERT, SESSION_DEBUG } = require('./messages') const tools = require('./tools') const {BaseRealm, BaseEngine} = require('./realm') const Session = require('./session') const validate_realm_regex = /^[a-z0-9_]+$/ function validateRealmName(realmName) { if (!realmName) { throw new Error('Realm name is empty') } if (typeof realmName !== 'string') { throw new Error('Realm name is not a string') } if (!validate_realm_regex.test(realmName)) { throw new Error('Realm name contains invalid characters (a-z, 0-9, _)') } } class Router extends EventEmitter { constructor () { super() this._realms = new Map() this._sessions = new Map() // symbol name, perhaps host this._id = '' this.on(SESSION_TX, function (session, data) { this.trace('[' + session.getSid() + '] >', data) }) this.on(SESSION_RX, function (session, msg) { this.trace('[' + session.getSid() + '] <', msg) }) this.on(SESSION_DEBUG, function (session, msg) { this.trace('[' + session.getSid() + '] DEBUG', msg) }) this.on(SESSION_ALERT, function (session, msg, data) { this.trace('[' + session.getSid() + ']', msg, data) }) this.setLogTrace(false) } setId (id) { this._id = id } getId () { return this._id } setLogTrace (trace) { if (trace) { this.trace = function () { console.log.apply(console, arguments) } } else { this.trace = function () {} } } makeSessionId () { return tools.randomId() } createSession () { const session = new Session(this.makeSessionId()) this.registerSession(session) return session } registerSession (session) { if (!this._sessions.has(session.sessionId)) { this._sessions.set(session.sessionId, session) this.emit('connection', session) } else { throw new Error('session id already registered ' + session.sessionId) } } removeSession (session) { session.cleanup() if (this._sessions.has(session.sessionId)) { this.emit('disconnection', session) this._sessions.delete(session.sessionId) } } getSession (sessionId) { return this._sessions.get(sessionId) } getRouterInfo () { let result = {} if (this._id) { result.id = this._id } return result } // to be overloaded to create custom engine createRealm (realmName) { return new BaseRealm(this, new BaseEngine()) } async initRealm (realmName, realm) { if (this._realms.has(realmName)) { throw Error('Realm "'+realmName+'" already set.') } this._realms.set(realmName, realm) await realm.getEngine().launchEngine(realmName) this.emit(REALM_CREATED, realm, realmName) } findRealm (realmName) { return this._realms.get(realmName) } async getRealm (realmName, callback) { if (this._realms.has(realmName)) { const realm = this._realms.get(realmName) if (typeof callback == 'function') { await callback(realm) } return realm } else { validateRealmName(realmName) const realm = this.createRealm(realmName) await this.initRealm(realmName, realm) if (typeof callback == 'function') { await callback(realm) } return realm } } } module.exports = Router