2015-10-07 15:28:34 +00:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
* @providesModule WebSocket
|
2016-02-16 11:28:05 +00:00
|
|
|
* @flow
|
2015-10-07 15:28:34 +00:00
|
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
|
2017-07-26 15:12:12 +00:00
|
|
|
const Blob = require('Blob');
|
|
|
|
const EventTarget = require('event-target-shim');
|
2016-05-12 15:29:39 +00:00
|
|
|
const NativeEventEmitter = require('NativeEventEmitter');
|
2018-01-26 17:06:14 +00:00
|
|
|
const BlobManager = require('BlobManager');
|
2017-07-26 15:12:12 +00:00
|
|
|
const NativeModules = require('NativeModules');
|
2016-04-18 22:42:42 +00:00
|
|
|
const Platform = require('Platform');
|
|
|
|
const WebSocketEvent = require('WebSocketEvent');
|
2015-10-07 15:28:34 +00:00
|
|
|
|
2017-09-06 10:25:01 +00:00
|
|
|
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
|
|
|
|
* found when Flow v0.54 was deployed. To see the error delete this comment and
|
|
|
|
* run Flow. */
|
2016-04-18 22:42:42 +00:00
|
|
|
const base64 = require('base64-js');
|
2017-07-26 15:12:12 +00:00
|
|
|
const binaryToBase64 = require('binaryToBase64');
|
|
|
|
const invariant = require('fbjs/lib/invariant');
|
|
|
|
|
|
|
|
const {WebSocketModule} = NativeModules;
|
2015-10-07 15:28:34 +00:00
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
import type EventSubscription from 'EventSubscription';
|
2015-12-22 17:22:01 +00:00
|
|
|
|
2017-07-26 15:12:12 +00:00
|
|
|
type ArrayBufferView =
|
|
|
|
| Int8Array
|
|
|
|
| Uint8Array
|
|
|
|
| Uint8ClampedArray
|
|
|
|
| Int16Array
|
|
|
|
| Uint16Array
|
|
|
|
| Int32Array
|
|
|
|
| Uint32Array
|
|
|
|
| Float32Array
|
|
|
|
| Float64Array
|
|
|
|
| DataView
|
|
|
|
|
|
|
|
type BinaryType = 'blob' | 'arraybuffer'
|
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
const CONNECTING = 0;
|
|
|
|
const OPEN = 1;
|
|
|
|
const CLOSING = 2;
|
|
|
|
const CLOSED = 3;
|
|
|
|
|
|
|
|
const CLOSE_NORMAL = 1000;
|
|
|
|
|
|
|
|
const WEBSOCKET_EVENTS = [
|
|
|
|
'close',
|
|
|
|
'error',
|
|
|
|
'message',
|
|
|
|
'open',
|
|
|
|
];
|
|
|
|
|
|
|
|
let nextWebSocketId = 0;
|
2015-10-07 15:28:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Browser-compatible WebSockets implementation.
|
|
|
|
*
|
|
|
|
* See https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
2016-01-20 19:00:21 +00:00
|
|
|
* See https://github.com/websockets/ws
|
2015-10-07 15:28:34 +00:00
|
|
|
*/
|
2016-04-27 19:25:38 +00:00
|
|
|
class WebSocket extends EventTarget(...WEBSOCKET_EVENTS) {
|
2016-04-18 22:42:42 +00:00
|
|
|
static CONNECTING = CONNECTING;
|
|
|
|
static OPEN = OPEN;
|
|
|
|
static CLOSING = CLOSING;
|
|
|
|
static CLOSED = CLOSED;
|
2015-10-07 15:28:34 +00:00
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
CONNECTING: number = CONNECTING;
|
|
|
|
OPEN: number = OPEN;
|
|
|
|
CLOSING: number = CLOSING;
|
|
|
|
CLOSED: number = CLOSED;
|
2015-10-07 15:28:34 +00:00
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
_socketId: number;
|
2016-05-12 15:29:39 +00:00
|
|
|
_eventEmitter: NativeEventEmitter;
|
2016-04-18 22:42:42 +00:00
|
|
|
_subscriptions: Array<EventSubscription>;
|
2017-07-26 15:12:12 +00:00
|
|
|
_binaryType: ?BinaryType;
|
2016-04-18 22:42:42 +00:00
|
|
|
|
|
|
|
onclose: ?Function;
|
|
|
|
onerror: ?Function;
|
|
|
|
onmessage: ?Function;
|
|
|
|
onopen: ?Function;
|
|
|
|
|
|
|
|
bufferedAmount: number;
|
|
|
|
extension: ?string;
|
|
|
|
protocol: ?string;
|
|
|
|
readyState: number = CONNECTING;
|
|
|
|
url: ?string;
|
|
|
|
|
2017-07-26 15:12:12 +00:00
|
|
|
// This module depends on the native `WebSocketModule` module. If you don't include it,
|
2017-06-01 15:20:57 +00:00
|
|
|
// `WebSocket.isAvailable` will return `false`, and WebSocket constructor will throw an error
|
2017-07-26 15:12:12 +00:00
|
|
|
static isAvailable: boolean = !!WebSocketModule;
|
2017-06-01 15:20:57 +00:00
|
|
|
|
WebSocket API change to make room for other connection options (SSL pinning)
Summary:
This is a simple groundwork PR to allow options to be passed to the `WebSocket` constructor. It represents a minor change to an undocumented part of the API, moving `headers` to within `options`.
This will be a BC for anyone manually specifying headers other than `origin` but a) that's not a common use case with WebSockets and b) it's not documented even in code and wouldn't currently pass a flow check.
NB: The third argument to the WebSocket constructor isn't part of the W3C spec, so I think this is a good place for RN-specific named parameters, better than adding a fourth argument. `protocols` needs to stay where it is, in line with the spec.
If this goes through I'd like to build on it by adding an additional connection option for SSL certificate pinning, as already supported by the underlying `okhttp` and `RCTSRWebSocket`. It could later be expanded for various other uses.
Currently, there's no way for a `WebSocket` user to specify any connection options other than url, protocol and headers. The fact that `WebSocket` connects in its constructor means any options have to go in there.
Connect to a websocket server using iOS and Android, observe the connection headers:
1. Without specifying `origin`, the default header should be set
2. Specifying it in the old way `new WebSocket(url, protocols, { origin: 'customorigin.com' })`
3. Specifying it in the new way `new WebSocket(url, protocols, { headers: { origin: 'customorigin.com' }})`.
I've tested myself using the test app with iOS and Android.
Closes https://github.com/facebook/react-native/pull/15334
Differential Revision: D5601675
Pulled By: javache
fbshipit-source-id: 5959d03a3e1d269b2c6775f3e0cf071ff08617bf
2017-08-10 12:59:36 +00:00
|
|
|
constructor(url: string, protocols: ?string | ?Array<string>, options: ?{headers?: {origin?: string}}) {
|
2016-04-18 22:42:42 +00:00
|
|
|
super();
|
|
|
|
if (typeof protocols === 'string') {
|
|
|
|
protocols = [protocols];
|
|
|
|
}
|
2015-10-07 15:28:34 +00:00
|
|
|
|
WebSocket API change to make room for other connection options (SSL pinning)
Summary:
This is a simple groundwork PR to allow options to be passed to the `WebSocket` constructor. It represents a minor change to an undocumented part of the API, moving `headers` to within `options`.
This will be a BC for anyone manually specifying headers other than `origin` but a) that's not a common use case with WebSockets and b) it's not documented even in code and wouldn't currently pass a flow check.
NB: The third argument to the WebSocket constructor isn't part of the W3C spec, so I think this is a good place for RN-specific named parameters, better than adding a fourth argument. `protocols` needs to stay where it is, in line with the spec.
If this goes through I'd like to build on it by adding an additional connection option for SSL certificate pinning, as already supported by the underlying `okhttp` and `RCTSRWebSocket`. It could later be expanded for various other uses.
Currently, there's no way for a `WebSocket` user to specify any connection options other than url, protocol and headers. The fact that `WebSocket` connects in its constructor means any options have to go in there.
Connect to a websocket server using iOS and Android, observe the connection headers:
1. Without specifying `origin`, the default header should be set
2. Specifying it in the old way `new WebSocket(url, protocols, { origin: 'customorigin.com' })`
3. Specifying it in the new way `new WebSocket(url, protocols, { headers: { origin: 'customorigin.com' }})`.
I've tested myself using the test app with iOS and Android.
Closes https://github.com/facebook/react-native/pull/15334
Differential Revision: D5601675
Pulled By: javache
fbshipit-source-id: 5959d03a3e1d269b2c6775f3e0cf071ff08617bf
2017-08-10 12:59:36 +00:00
|
|
|
const {headers = {}, ...unrecognized} = options || {};
|
|
|
|
|
|
|
|
// Preserve deprecated backwards compatibility for the 'origin' option
|
|
|
|
if (unrecognized && typeof unrecognized.origin === 'string') {
|
|
|
|
console.warn('Specifying `origin` as a WebSocket connection option is deprecated. Include it under `headers` instead.');
|
2017-09-06 10:25:01 +00:00
|
|
|
/* $FlowFixMe(>=0.54.0 site=react_native_fb,react_native_oss) This
|
|
|
|
* comment suppresses an error found when Flow v0.54 was deployed. To see
|
|
|
|
* the error delete this comment and run Flow. */
|
WebSocket API change to make room for other connection options (SSL pinning)
Summary:
This is a simple groundwork PR to allow options to be passed to the `WebSocket` constructor. It represents a minor change to an undocumented part of the API, moving `headers` to within `options`.
This will be a BC for anyone manually specifying headers other than `origin` but a) that's not a common use case with WebSockets and b) it's not documented even in code and wouldn't currently pass a flow check.
NB: The third argument to the WebSocket constructor isn't part of the W3C spec, so I think this is a good place for RN-specific named parameters, better than adding a fourth argument. `protocols` needs to stay where it is, in line with the spec.
If this goes through I'd like to build on it by adding an additional connection option for SSL certificate pinning, as already supported by the underlying `okhttp` and `RCTSRWebSocket`. It could later be expanded for various other uses.
Currently, there's no way for a `WebSocket` user to specify any connection options other than url, protocol and headers. The fact that `WebSocket` connects in its constructor means any options have to go in there.
Connect to a websocket server using iOS and Android, observe the connection headers:
1. Without specifying `origin`, the default header should be set
2. Specifying it in the old way `new WebSocket(url, protocols, { origin: 'customorigin.com' })`
3. Specifying it in the new way `new WebSocket(url, protocols, { headers: { origin: 'customorigin.com' }})`.
I've tested myself using the test app with iOS and Android.
Closes https://github.com/facebook/react-native/pull/15334
Differential Revision: D5601675
Pulled By: javache
fbshipit-source-id: 5959d03a3e1d269b2c6775f3e0cf071ff08617bf
2017-08-10 12:59:36 +00:00
|
|
|
headers.origin = unrecognized.origin;
|
2017-09-06 10:25:01 +00:00
|
|
|
/* $FlowFixMe(>=0.54.0 site=react_native_fb,react_native_oss) This
|
|
|
|
* comment suppresses an error found when Flow v0.54 was deployed. To see
|
|
|
|
* the error delete this comment and run Flow. */
|
WebSocket API change to make room for other connection options (SSL pinning)
Summary:
This is a simple groundwork PR to allow options to be passed to the `WebSocket` constructor. It represents a minor change to an undocumented part of the API, moving `headers` to within `options`.
This will be a BC for anyone manually specifying headers other than `origin` but a) that's not a common use case with WebSockets and b) it's not documented even in code and wouldn't currently pass a flow check.
NB: The third argument to the WebSocket constructor isn't part of the W3C spec, so I think this is a good place for RN-specific named parameters, better than adding a fourth argument. `protocols` needs to stay where it is, in line with the spec.
If this goes through I'd like to build on it by adding an additional connection option for SSL certificate pinning, as already supported by the underlying `okhttp` and `RCTSRWebSocket`. It could later be expanded for various other uses.
Currently, there's no way for a `WebSocket` user to specify any connection options other than url, protocol and headers. The fact that `WebSocket` connects in its constructor means any options have to go in there.
Connect to a websocket server using iOS and Android, observe the connection headers:
1. Without specifying `origin`, the default header should be set
2. Specifying it in the old way `new WebSocket(url, protocols, { origin: 'customorigin.com' })`
3. Specifying it in the new way `new WebSocket(url, protocols, { headers: { origin: 'customorigin.com' }})`.
I've tested myself using the test app with iOS and Android.
Closes https://github.com/facebook/react-native/pull/15334
Differential Revision: D5601675
Pulled By: javache
fbshipit-source-id: 5959d03a3e1d269b2c6775f3e0cf071ff08617bf
2017-08-10 12:59:36 +00:00
|
|
|
delete unrecognized.origin;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Warn about and discard anything else
|
|
|
|
if (Object.keys(unrecognized).length > 0) {
|
|
|
|
console.warn('Unrecognized WebSocket connection option(s) `' + Object.keys(unrecognized).join('`, `') + '`. '
|
|
|
|
+ 'Did you mean to put these under `headers`?');
|
|
|
|
}
|
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
if (!Array.isArray(protocols)) {
|
|
|
|
protocols = null;
|
|
|
|
}
|
2015-10-07 15:28:34 +00:00
|
|
|
|
2017-06-01 15:20:57 +00:00
|
|
|
if (!WebSocket.isAvailable) {
|
|
|
|
throw new Error('Cannot initialize WebSocket module. ' +
|
2017-07-26 15:12:12 +00:00
|
|
|
'Native module WebSocketModule is missing.');
|
2017-06-01 15:20:57 +00:00
|
|
|
}
|
|
|
|
|
2017-07-26 15:12:12 +00:00
|
|
|
this._eventEmitter = new NativeEventEmitter(WebSocketModule);
|
2016-04-18 22:42:42 +00:00
|
|
|
this._socketId = nextWebSocketId++;
|
|
|
|
this._registerEvents();
|
WebSocket API change to make room for other connection options (SSL pinning)
Summary:
This is a simple groundwork PR to allow options to be passed to the `WebSocket` constructor. It represents a minor change to an undocumented part of the API, moving `headers` to within `options`.
This will be a BC for anyone manually specifying headers other than `origin` but a) that's not a common use case with WebSockets and b) it's not documented even in code and wouldn't currently pass a flow check.
NB: The third argument to the WebSocket constructor isn't part of the W3C spec, so I think this is a good place for RN-specific named parameters, better than adding a fourth argument. `protocols` needs to stay where it is, in line with the spec.
If this goes through I'd like to build on it by adding an additional connection option for SSL certificate pinning, as already supported by the underlying `okhttp` and `RCTSRWebSocket`. It could later be expanded for various other uses.
Currently, there's no way for a `WebSocket` user to specify any connection options other than url, protocol and headers. The fact that `WebSocket` connects in its constructor means any options have to go in there.
Connect to a websocket server using iOS and Android, observe the connection headers:
1. Without specifying `origin`, the default header should be set
2. Specifying it in the old way `new WebSocket(url, protocols, { origin: 'customorigin.com' })`
3. Specifying it in the new way `new WebSocket(url, protocols, { headers: { origin: 'customorigin.com' }})`.
I've tested myself using the test app with iOS and Android.
Closes https://github.com/facebook/react-native/pull/15334
Differential Revision: D5601675
Pulled By: javache
fbshipit-source-id: 5959d03a3e1d269b2c6775f3e0cf071ff08617bf
2017-08-10 12:59:36 +00:00
|
|
|
WebSocketModule.connect(url, protocols, { headers }, this._socketId);
|
2017-07-26 15:12:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get binaryType(): ?BinaryType {
|
|
|
|
return this._binaryType;
|
|
|
|
}
|
|
|
|
|
|
|
|
set binaryType(binaryType: BinaryType): void {
|
|
|
|
if (binaryType !== 'blob' && binaryType !== 'arraybuffer') {
|
|
|
|
throw new Error('binaryType must be either \'blob\' or \'arraybuffer\'');
|
|
|
|
}
|
|
|
|
if (this._binaryType === 'blob' || binaryType === 'blob') {
|
2018-01-26 17:06:14 +00:00
|
|
|
invariant(BlobManager.isAvailable, 'Native module BlobModule is required for blob support');
|
|
|
|
if (binaryType === 'blob') {
|
|
|
|
BlobManager.addWebSocketHandler(this._socketId);
|
|
|
|
} else {
|
|
|
|
BlobManager.removeWebSocketHandler(this._socketId);
|
2017-07-26 15:12:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
this._binaryType = binaryType;
|
2015-10-07 15:28:34 +00:00
|
|
|
}
|
|
|
|
|
2018-01-26 17:06:14 +00:00
|
|
|
get binaryType(): ?BinaryType {
|
|
|
|
return this._binaryType;
|
|
|
|
}
|
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
close(code?: number, reason?: string): void {
|
|
|
|
if (this.readyState === this.CLOSING ||
|
|
|
|
this.readyState === this.CLOSED) {
|
|
|
|
return;
|
|
|
|
}
|
2015-10-07 15:28:34 +00:00
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
this.readyState = this.CLOSING;
|
|
|
|
this._close(code, reason);
|
2015-10-07 15:28:34 +00:00
|
|
|
}
|
|
|
|
|
2017-07-26 15:12:12 +00:00
|
|
|
send(data: string | ArrayBuffer | ArrayBufferView | Blob): void {
|
2016-04-18 22:42:42 +00:00
|
|
|
if (this.readyState === this.CONNECTING) {
|
|
|
|
throw new Error('INVALID_STATE_ERR');
|
|
|
|
}
|
|
|
|
|
2017-07-26 15:12:12 +00:00
|
|
|
if (data instanceof Blob) {
|
2018-01-26 17:06:14 +00:00
|
|
|
invariant(BlobManager.isAvailable, 'Native module BlobModule is required for blob support');
|
|
|
|
BlobManager.sendOverSocket(data, this._socketId);
|
2017-07-26 15:12:12 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
if (typeof data === 'string') {
|
2017-07-26 15:12:12 +00:00
|
|
|
WebSocketModule.send(data, this._socketId);
|
2016-04-20 15:52:22 +00:00
|
|
|
return;
|
2016-04-18 22:42:42 +00:00
|
|
|
}
|
2016-04-20 15:52:22 +00:00
|
|
|
|
2017-01-21 02:40:28 +00:00
|
|
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
2017-07-26 15:12:12 +00:00
|
|
|
WebSocketModule.sendBinary(binaryToBase64(data), this._socketId);
|
2016-09-08 14:28:31 +00:00
|
|
|
return;
|
2016-04-20 15:52:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error('Unsupported data type');
|
2015-10-07 15:28:34 +00:00
|
|
|
}
|
|
|
|
|
2016-07-05 12:52:24 +00:00
|
|
|
ping(): void {
|
|
|
|
if (this.readyState === this.CONNECTING) {
|
|
|
|
throw new Error('INVALID_STATE_ERR');
|
|
|
|
}
|
|
|
|
|
2017-07-26 15:12:12 +00:00
|
|
|
WebSocketModule.ping(this._socketId);
|
2016-07-05 12:52:24 +00:00
|
|
|
}
|
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
_close(code?: number, reason?: string): void {
|
2015-10-07 15:28:34 +00:00
|
|
|
if (Platform.OS === 'android') {
|
2016-04-18 22:42:42 +00:00
|
|
|
// See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
|
2016-05-12 15:29:39 +00:00
|
|
|
const statusCode = typeof code === 'number' ? code : CLOSE_NORMAL;
|
|
|
|
const closeReason = typeof reason === 'string' ? reason : '';
|
2017-07-26 15:12:12 +00:00
|
|
|
WebSocketModule.close(statusCode, closeReason, this._socketId);
|
2015-10-07 15:28:34 +00:00
|
|
|
} else {
|
2017-07-26 15:12:12 +00:00
|
|
|
WebSocketModule.close(this._socketId);
|
2015-10-07 15:28:34 +00:00
|
|
|
}
|
2018-01-26 17:06:14 +00:00
|
|
|
|
|
|
|
if (BlobManager.isAvailable && this._binaryType === 'blob') {
|
|
|
|
BlobManager.removeWebSocketHandler(this._socketId);
|
|
|
|
}
|
2015-10-07 15:28:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_unregisterEvents(): void {
|
2016-04-18 22:42:42 +00:00
|
|
|
this._subscriptions.forEach(e => e.remove());
|
|
|
|
this._subscriptions = [];
|
2015-10-07 15:28:34 +00:00
|
|
|
}
|
|
|
|
|
2016-04-18 22:42:42 +00:00
|
|
|
_registerEvents(): void {
|
|
|
|
this._subscriptions = [
|
2016-05-12 15:29:39 +00:00
|
|
|
this._eventEmitter.addListener('websocketMessage', ev => {
|
2016-04-18 22:42:42 +00:00
|
|
|
if (ev.id !== this._socketId) {
|
2015-10-07 15:28:34 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-07-26 15:12:12 +00:00
|
|
|
let data = ev.data;
|
|
|
|
switch (ev.type) {
|
|
|
|
case 'binary':
|
|
|
|
data = base64.toByteArray(ev.data).buffer;
|
|
|
|
break;
|
|
|
|
case 'blob':
|
2018-01-26 17:06:14 +00:00
|
|
|
data = BlobManager.createFromOptions(ev.data);
|
2017-07-26 15:12:12 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
this.dispatchEvent(new WebSocketEvent('message', { data }));
|
2015-10-07 15:28:34 +00:00
|
|
|
}),
|
2016-05-12 15:29:39 +00:00
|
|
|
this._eventEmitter.addListener('websocketOpen', ev => {
|
2016-04-18 22:42:42 +00:00
|
|
|
if (ev.id !== this._socketId) {
|
2015-10-07 15:28:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.readyState = this.OPEN;
|
2016-05-12 15:29:39 +00:00
|
|
|
this.dispatchEvent(new WebSocketEvent('open'));
|
2015-10-07 15:28:34 +00:00
|
|
|
}),
|
2016-05-12 15:29:39 +00:00
|
|
|
this._eventEmitter.addListener('websocketClosed', ev => {
|
2016-04-18 22:42:42 +00:00
|
|
|
if (ev.id !== this._socketId) {
|
2015-10-07 15:28:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.readyState = this.CLOSED;
|
2016-05-12 15:29:39 +00:00
|
|
|
this.dispatchEvent(new WebSocketEvent('close', {
|
|
|
|
code: ev.code,
|
|
|
|
reason: ev.reason,
|
|
|
|
}));
|
2015-10-07 15:28:34 +00:00
|
|
|
this._unregisterEvents();
|
2015-10-27 15:33:38 +00:00
|
|
|
this.close();
|
2015-10-07 15:28:34 +00:00
|
|
|
}),
|
2016-05-12 15:29:39 +00:00
|
|
|
this._eventEmitter.addListener('websocketFailed', ev => {
|
2016-04-18 22:42:42 +00:00
|
|
|
if (ev.id !== this._socketId) {
|
2015-10-07 15:28:34 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-09-09 00:01:10 +00:00
|
|
|
this.readyState = this.CLOSED;
|
2016-05-12 15:29:39 +00:00
|
|
|
this.dispatchEvent(new WebSocketEvent('error', {
|
|
|
|
message: ev.message,
|
|
|
|
}));
|
|
|
|
this.dispatchEvent(new WebSocketEvent('close', {
|
|
|
|
message: ev.message,
|
|
|
|
}));
|
2015-10-07 15:28:34 +00:00
|
|
|
this._unregisterEvents();
|
2015-10-27 15:33:38 +00:00
|
|
|
this.close();
|
2015-10-07 15:28:34 +00:00
|
|
|
})
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = WebSocket;
|