UNPKG

diffusion

Version:

Diffusion JavaScript client

116 lines (95 loc) 3.28 kB
/*eslint valid-jsdoc: "off"*/ /*global Uint8Array*/ var encodeAsString = require('v4-stack/credential-tunnel').encodeAsString; var Emitter = require('events/emitter'); var log = require('util/logger').create('Websocket transport'); /** * Construct a valid websocket URI from the given options. * * @param {Options} opts - The connection options. * @returns {String} The connection URI */ function constructURI(req, opts) { var scheme = opts.secure ? 'wss' : 'ws'; var uri = scheme + "://" + opts.host + ":" + opts.port + opts.path; uri += '?ty=' + req.type; uri += '&v=' + req.version; uri += '&ca=' + req.capabilities; uri += '&r=' + opts.reconnect.timeout; if (req.token) { uri += '&c=' + encodeURIComponent(req.token); uri += "&cs=" + req.availableClientSequence; uri += "&ss=" + req.lastServerSequence; } if (opts.properties) { uri += "&sp=" + encodeURIComponent(JSON.stringify(opts.properties)); } if (opts.principal) { uri += "&username=" + encodeURIComponent(opts.principal); uri += "&password=" + encodeURIComponent(encodeAsString(opts.credentials)); } return uri; } function WSTransport(opts, constructor) { var emitter = Emitter.assign(this); var handler = function(message) { if (message.data.length > opts.maxMessageSize) { emitter.error(new Error( "Received message of size: " + message.data.length + ", exceeding max message size: " + opts.maxMessageSize)); } else { emitter.emit('data', new Buffer(new Uint8Array(message.data))); } }; var socket; /** * Establish a websocket connection, with provided connection options and * callback functions. * * @param {Object} req - Connection request * @param {Function} handshake - The handshake handler function * @param {Function} dataWritten - The data written handler */ this.connect = function connect(req, handshake) { try { var uri = constructURI(req, opts); socket = new constructor(uri); log.debug("Created websocket", uri); } catch (error) { throw new Error('Unable to construct WebSocket', error); } socket.binaryType = "arraybuffer"; socket.onmessage = function(msg) { socket.onmessage = handler; socket.onerror = emitter.error; handshake(new Buffer(new Uint8Array(msg.data))); }; socket.onclose = emitter.close; socket.onerror = emitter.close; }; /** * Send a binary message to the server. * * @param {Buffer} message - The message to send */ this.dispatch = function dispatch(message) { log.debug("Sending websocket message", message); try { socket.send(message); return true; } catch (err) { log.error("Websocket send error", err); return false; } }; /** * Directly close the websocket connection. */ this.close = function() { log.debug("Closing websocket"); socket.close(1000); }; } module.exports = WSTransport;