-
Notifications
You must be signed in to change notification settings - Fork 9
/
index.js
107 lines (82 loc) · 3.39 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// import {NativeModules} from 'react-native'
// const {WebSocketModule} = NativeModules;
import WebSocketModule from 'react-native/Libraries/WebSocket/NativeWebSocketModule';
let settings = {
/** The number of milliseconds to delay before attempting to reconnect. */
reconnectInterval: 1000,
/** The maximum number of milliseconds to delay a reconnection attempt. */
maxReconnectInterval: 30000,
/** The rate of increase of the reconnect delay. Allows reconnect attempts to back off when problems persist. */
reconnectDecay: 1.5,
/** The maximum time in milliseconds to wait for a connection to succeed before closing and retrying. */
timeoutInterval: 2000,
/** The maximum number of reconnection attempts to make. Unlimited if null. */
maxReconnectAttempts: null,
};
class ReconnectingWebSocket extends WebSocket{
constructor(url,protocols,options) {
if (!options) { options = {}; }
super(url,protocols,{headers:options.headers});
// Overwrite and define settings with options if they exist.
for (let key in settings) {
if (typeof options[key] !== 'undefined') {
this[key] = options[key];
} else {
this[key] = settings[key];
}
}
// These should be treated as read-only properties
/** The URL as resolved by the constructor. This is always an absolute URL. Read only. */
this.url = url;
/** The number of attempted reconnects since starting, or the last successful connection. Read only. */
this.reconnectAttempts = 0;
this.protocols = protocols;
this.timeout = null;
}
_unregisterEvents(){
if (this.maxReconnectAttempts && this.reconnectAttempts > this.maxReconnectAttempts) {
return super._unregisterEvents();
}
}
_registerEvents(){
super._registerEvents();
this._subscriptions.push(
/** @Override onopen **/
this._eventEmitter.addListener('websocketOpen', ev => {
if (ev.id !== this._socketId) {
return;
}
this.timeout && clearTimeout(this.timeout);
this.reconnectAttempts = 0
}),
/** @Override onerror **/
this._eventEmitter.addListener('websocketFailed', ev => {
if (ev.id !== this._socketId) {
return;
}
let _timeout = this.reconnectInterval * Math.pow(this.reconnectDecay, this.reconnectAttempts);
this.timeout && clearTimeout(this.timeout);
this.timeout = setTimeout(()=>{
this.reconnectAttempts++;
this.reconnect()
}, _timeout > this.maxReconnectInterval ? this.maxReconnectInterval : _timeout);
})
)
}
reconnect(){
if (this.maxReconnectAttempts && this.reconnectAttempts > this.maxReconnectAttempts) {
return;
}
this.timeout = setTimeout(()=>{
WebSocketModule.connect(
this.url,
this.protocols,
this.headers || {},
this._socketId,
);
this.onconnecting({reconnectAttempts:this.reconnectAttempts})
}, this.reconnectInterval);
}
onconnecting(){}
}
export default ReconnectingWebSocket;