dispatch/client/js/utils/Socket.js

99 lines
2.1 KiB
JavaScript
Raw Normal View History

2015-12-28 23:34:32 +00:00
import Backoff from 'backo';
export default class Socket {
constructor(host) {
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
this.url = `${protocol}://${host}/ws${window.location.pathname}`;
2015-12-28 23:34:32 +00:00
this.connectTimeout = 20000;
this.pingTimeout = 30000;
this.backoff = new Backoff({
min: 1000,
max: 5000,
jitter: 0.25
});
this.handlers = [];
this.connected = false;
2015-12-28 23:34:32 +00:00
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
2015-12-28 23:34:32 +00:00
this.timeoutConnect = setTimeout(() => {
this.ws.close();
this.retry();
}, this.connectTimeout);
this.ws.onopen = () => {
this.connected = true;
2017-05-29 04:16:24 +00:00
this.emit('_connected', true);
2015-12-28 23:34:32 +00:00
clearTimeout(this.timeoutConnect);
this.backoff.reset();
this.setTimeoutPing();
};
this.ws.onclose = () => {
if (this.connected) {
this.connected = false;
this.emit('_connected', false);
}
2015-12-28 23:34:32 +00:00
clearTimeout(this.timeoutConnect);
clearTimeout(this.timeoutPing);
if (!this.closing) {
this.retry();
}
this.closing = false;
};
this.ws.onerror = () => {
clearTimeout(this.timeoutConnect);
clearTimeout(this.timeoutPing);
this.closing = true;
this.ws.close();
this.retry();
};
2018-04-05 23:46:22 +00:00
this.ws.onmessage = e => {
2015-12-28 23:34:32 +00:00
this.setTimeoutPing();
const msg = JSON.parse(e.data);
if (msg.type === 'ping') {
this.send('pong');
return;
2015-12-28 23:34:32 +00:00
}
this.emit(msg.type, msg.data);
};
}
retry() {
setTimeout(() => this.connect(), this.backoff.duration());
}
send(type, data) {
this.ws.send(JSON.stringify({ type, data }));
}
setTimeoutPing() {
clearTimeout(this.timeoutPing);
this.timeoutPing = setTimeout(() => {
this.closing = true;
this.ws.close();
this.connect();
}, this.pingTimeout);
}
onMessage(handler) {
this.handlers.push(handler);
}
emit(type, data) {
for (let i = 0; i < this.handlers.length; i++) {
this.handlers[i](type, data);
}
}
2015-12-28 23:34:32 +00:00
}