/**
* @module flitter-socket/Controller
*/
const ConnectionManager = require('./ConnectionManager')
const LibFlitterController = require('libflitter/controller/Controller')
/**
* Special class of controller that includes bootstrap methods for
* using flitter-socket.
* @class
* @extends module:libflitter/controller/Controller
*/
class Controller extends LibFlitterController {
/**
* Initialize the controller.
*/
constructor() {
super()
/**
* Map of connection IDs to open connection managers.
* @type {Object}
*/
this.connections = {}
}
/**
* Route helper for bootstrapping a transactional websocket connection.
* Wraps the socket in a new {flitter-socket/ConnectionManager~ConnectionManager} and
* adds it to this.connections.
* @param {WebSocket} ws - the incoming websocket
* @param {express/Request} req - the connection request
*/
_connect(ws, req){
const cm = new ConnectionManager(ws, req, this)
this.connections[cm.id] = cm
cm.on_close(() => {
this.connections[cm.id] = undefined
})
this._client_connected(cm)
}
/**
* Send a request to one websocket client.
* @param {string} endpoint - the endpoint to request data from
* @param {object} data - the request's body data
* @param {function} handler - callback function called when a valid client response has been received.
* @param {string} client_id - connection id to whom the request should be sent.
*/
_request(endpoint, data, handler, client_id){
if ( client_id){
if ( !Object.keys(this.connections).includes(client_id) ) throw new Error('No connection exists with the specified id: '+client_id)
this.connections[client_id]._request(endpoint, data, handler)
}
}
/**
* Send a request to all connected clients.
* @param {string} endpoint - the endpoint to request data from
* @param {object} data - the request's body data
* @param {function} handler - callback function called each time a client response is received
*/
_blast(endpoint, data, handler){
Object.keys(this.connections).forEach(client_id => {
this._request(endpoint, data, handler, client_id)
})
}
/**
* Async wrapper for this._request().
* @param {string} endpoint - the endpoint to request data from
* @param {object} data - the request's body data
* @param {string} client_id - connection id to whom the request should be sent.
*/
_request_async(endpoint, data, client_id){
return new Promise(resolve => {
this._request(endpoint, data, (...args) => resolve(...args), client_id)
})
}
/**
* Called when a new connection manager has been started.
* @param {module:flitter-socket/ConnectionManager~ConnectionManager} connection_manager
*/
_client_connected(connection_manager){}
}
module.exports = exports = Controller