aboutsummaryrefslogtreecommitdiffhomepage
path: root/node_modules/engine.io-client/lib/transports/websocket.js
diff options
context:
space:
mode:
authorYaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx>2017-11-29 11:44:34 +0300
committerYaroslav De La Peña Smirnov <yaros.rus_89@live.com.mx>2017-11-29 11:44:34 +0300
commit67fdec20726e48ba3a934cb25bb30d47ec4a4f29 (patch)
tree37fd9f4f0b0c20103e1646fc83021e4765de3680 /node_modules/engine.io-client/lib/transports/websocket.js
downloadspanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.tar.gz
spanish-checkers-67fdec20726e48ba3a934cb25bb30d47ec4a4f29.zip
Initial commit, version 0.5.3
Diffstat (limited to 'node_modules/engine.io-client/lib/transports/websocket.js')
-rw-r--r--node_modules/engine.io-client/lib/transports/websocket.js286
1 files changed, 286 insertions, 0 deletions
diff --git a/node_modules/engine.io-client/lib/transports/websocket.js b/node_modules/engine.io-client/lib/transports/websocket.js
new file mode 100644
index 0000000..de14ba0
--- /dev/null
+++ b/node_modules/engine.io-client/lib/transports/websocket.js
@@ -0,0 +1,286 @@
+/**
+ * Module dependencies.
+ */
+
+var Transport = require('../transport');
+var parser = require('engine.io-parser');
+var parseqs = require('parseqs');
+var inherit = require('component-inherit');
+var yeast = require('yeast');
+var debug = require('debug')('engine.io-client:websocket');
+var BrowserWebSocket = global.WebSocket || global.MozWebSocket;
+var NodeWebSocket;
+if (typeof window === 'undefined') {
+ try {
+ NodeWebSocket = require('ws');
+ } catch (e) { }
+}
+
+/**
+ * Get either the `WebSocket` or `MozWebSocket` globals
+ * in the browser or try to resolve WebSocket-compatible
+ * interface exposed by `ws` for Node-like environment.
+ */
+
+var WebSocket = BrowserWebSocket;
+if (!WebSocket && typeof window === 'undefined') {
+ WebSocket = NodeWebSocket;
+}
+
+/**
+ * Module exports.
+ */
+
+module.exports = WS;
+
+/**
+ * WebSocket transport constructor.
+ *
+ * @api {Object} connection options
+ * @api public
+ */
+
+function WS (opts) {
+ var forceBase64 = (opts && opts.forceBase64);
+ if (forceBase64) {
+ this.supportsBinary = false;
+ }
+ this.perMessageDeflate = opts.perMessageDeflate;
+ this.usingBrowserWebSocket = BrowserWebSocket && !opts.forceNode;
+ this.protocols = opts.protocols;
+ if (!this.usingBrowserWebSocket) {
+ WebSocket = NodeWebSocket;
+ }
+ Transport.call(this, opts);
+}
+
+/**
+ * Inherits from Transport.
+ */
+
+inherit(WS, Transport);
+
+/**
+ * Transport name.
+ *
+ * @api public
+ */
+
+WS.prototype.name = 'websocket';
+
+/*
+ * WebSockets support binary
+ */
+
+WS.prototype.supportsBinary = true;
+
+/**
+ * Opens socket.
+ *
+ * @api private
+ */
+
+WS.prototype.doOpen = function () {
+ if (!this.check()) {
+ // let probe timeout
+ return;
+ }
+
+ var uri = this.uri();
+ var protocols = this.protocols;
+ var opts = {
+ agent: this.agent,
+ perMessageDeflate: this.perMessageDeflate
+ };
+
+ // SSL options for Node.js client
+ opts.pfx = this.pfx;
+ opts.key = this.key;
+ opts.passphrase = this.passphrase;
+ opts.cert = this.cert;
+ opts.ca = this.ca;
+ opts.ciphers = this.ciphers;
+ opts.rejectUnauthorized = this.rejectUnauthorized;
+ if (this.extraHeaders) {
+ opts.headers = this.extraHeaders;
+ }
+ if (this.localAddress) {
+ opts.localAddress = this.localAddress;
+ }
+
+ try {
+ this.ws = this.usingBrowserWebSocket ? (protocols ? new WebSocket(uri, protocols) : new WebSocket(uri)) : new WebSocket(uri, protocols, opts);
+ } catch (err) {
+ return this.emit('error', err);
+ }
+
+ if (this.ws.binaryType === undefined) {
+ this.supportsBinary = false;
+ }
+
+ if (this.ws.supports && this.ws.supports.binary) {
+ this.supportsBinary = true;
+ this.ws.binaryType = 'nodebuffer';
+ } else {
+ this.ws.binaryType = 'arraybuffer';
+ }
+
+ this.addEventListeners();
+};
+
+/**
+ * Adds event listeners to the socket
+ *
+ * @api private
+ */
+
+WS.prototype.addEventListeners = function () {
+ var self = this;
+
+ this.ws.onopen = function () {
+ self.onOpen();
+ };
+ this.ws.onclose = function () {
+ self.onClose();
+ };
+ this.ws.onmessage = function (ev) {
+ self.onData(ev.data);
+ };
+ this.ws.onerror = function (e) {
+ self.onError('websocket error', e);
+ };
+};
+
+/**
+ * Writes data to socket.
+ *
+ * @param {Array} array of packets.
+ * @api private
+ */
+
+WS.prototype.write = function (packets) {
+ var self = this;
+ this.writable = false;
+
+ // encodePacket efficient as it uses WS framing
+ // no need for encodePayload
+ var total = packets.length;
+ for (var i = 0, l = total; i < l; i++) {
+ (function (packet) {
+ parser.encodePacket(packet, self.supportsBinary, function (data) {
+ if (!self.usingBrowserWebSocket) {
+ // always create a new object (GH-437)
+ var opts = {};
+ if (packet.options) {
+ opts.compress = packet.options.compress;
+ }
+
+ if (self.perMessageDeflate) {
+ var len = 'string' === typeof data ? global.Buffer.byteLength(data) : data.length;
+ if (len < self.perMessageDeflate.threshold) {
+ opts.compress = false;
+ }
+ }
+ }
+
+ // Sometimes the websocket has already been closed but the browser didn't
+ // have a chance of informing us about it yet, in that case send will
+ // throw an error
+ try {
+ if (self.usingBrowserWebSocket) {
+ // TypeError is thrown when passing the second argument on Safari
+ self.ws.send(data);
+ } else {
+ self.ws.send(data, opts);
+ }
+ } catch (e) {
+ debug('websocket closed before onclose event');
+ }
+
+ --total || done();
+ });
+ })(packets[i]);
+ }
+
+ function done () {
+ self.emit('flush');
+
+ // fake drain
+ // defer to next tick to allow Socket to clear writeBuffer
+ setTimeout(function () {
+ self.writable = true;
+ self.emit('drain');
+ }, 0);
+ }
+};
+
+/**
+ * Called upon close
+ *
+ * @api private
+ */
+
+WS.prototype.onClose = function () {
+ Transport.prototype.onClose.call(this);
+};
+
+/**
+ * Closes socket.
+ *
+ * @api private
+ */
+
+WS.prototype.doClose = function () {
+ if (typeof this.ws !== 'undefined') {
+ this.ws.close();
+ }
+};
+
+/**
+ * Generates uri for connection.
+ *
+ * @api private
+ */
+
+WS.prototype.uri = function () {
+ var query = this.query || {};
+ var schema = this.secure ? 'wss' : 'ws';
+ var port = '';
+
+ // avoid port if default for schema
+ if (this.port && (('wss' === schema && Number(this.port) !== 443) ||
+ ('ws' === schema && Number(this.port) !== 80))) {
+ port = ':' + this.port;
+ }
+
+ // append timestamp to URI
+ if (this.timestampRequests) {
+ query[this.timestampParam] = yeast();
+ }
+
+ // communicate binary support capabilities
+ if (!this.supportsBinary) {
+ query.b64 = 1;
+ }
+
+ query = parseqs.encode(query);
+
+ // prepend ? to query
+ if (query.length) {
+ query = '?' + query;
+ }
+
+ var ipv6 = this.hostname.indexOf(':') !== -1;
+ return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
+};
+
+/**
+ * Feature detection for WebSocket.
+ *
+ * @return {Boolean} whether this transport is available.
+ * @api public
+ */
+
+WS.prototype.check = function () {
+ return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);
+};