2020-03-27 20:59:38 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
import WebSocketClient from 'websocket.js';
|
|
|
|
|
|
|
|
const randomIntUpTo = max => Math.floor(Math.random() * Math.floor(max));
|
|
|
|
|
|
|
|
export function connectStream(path, pollingRefresh = null, callbacks = () => ({ onConnect() {}, onDisconnect() {}, onReceive() {} })) {
|
|
|
|
return (dispatch, getState) => {
|
2020-04-05 21:28:08 +00:00
|
|
|
const streamingAPIBaseURL = getState().getIn(['instance', 'urls', 'streaming_api']);
|
2020-04-05 23:39:22 +00:00
|
|
|
const accessToken = getState().getIn(['auth', 'user', 'access_token']);
|
2020-03-27 20:59:38 +00:00
|
|
|
const { onConnect, onDisconnect, onReceive } = callbacks(dispatch, getState);
|
|
|
|
|
|
|
|
let polling = null;
|
|
|
|
|
|
|
|
const setupPolling = () => {
|
|
|
|
pollingRefresh(dispatch, () => {
|
|
|
|
polling = setTimeout(() => setupPolling(), 20000 + randomIntUpTo(20000));
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const clearPolling = () => {
|
|
|
|
if (polling) {
|
|
|
|
clearTimeout(polling);
|
|
|
|
polling = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const subscription = getStream(streamingAPIBaseURL, accessToken, path, {
|
2020-04-14 21:47:35 +00:00
|
|
|
connected() {
|
2020-03-27 20:59:38 +00:00
|
|
|
if (pollingRefresh) {
|
|
|
|
clearPolling();
|
|
|
|
}
|
|
|
|
|
|
|
|
onConnect();
|
|
|
|
},
|
|
|
|
|
2020-04-14 21:47:35 +00:00
|
|
|
disconnected() {
|
2020-03-27 20:59:38 +00:00
|
|
|
if (pollingRefresh) {
|
|
|
|
polling = setTimeout(() => setupPolling(), randomIntUpTo(40000));
|
|
|
|
}
|
|
|
|
|
|
|
|
onDisconnect();
|
|
|
|
},
|
|
|
|
|
2020-04-14 21:47:35 +00:00
|
|
|
received(data) {
|
2020-03-27 20:59:38 +00:00
|
|
|
onReceive(data);
|
|
|
|
},
|
|
|
|
|
2020-04-14 21:47:35 +00:00
|
|
|
reconnected() {
|
2020-03-27 20:59:38 +00:00
|
|
|
if (pollingRefresh) {
|
|
|
|
clearPolling();
|
|
|
|
pollingRefresh(dispatch);
|
|
|
|
}
|
|
|
|
|
|
|
|
onConnect();
|
|
|
|
},
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
const disconnect = () => {
|
|
|
|
if (subscription) {
|
|
|
|
subscription.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
clearPolling();
|
|
|
|
};
|
|
|
|
|
|
|
|
return disconnect;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default function getStream(streamingAPIBaseURL, accessToken, stream, { connected, received, disconnected, reconnected }) {
|
|
|
|
const params = [ `stream=${stream}` ];
|
|
|
|
|
|
|
|
const ws = new WebSocketClient(`${streamingAPIBaseURL}/api/v1/streaming/?${params.join('&')}`, accessToken);
|
|
|
|
|
|
|
|
ws.onopen = connected;
|
|
|
|
ws.onclose = disconnected;
|
|
|
|
ws.onreconnect = reconnected;
|
|
|
|
|
2020-04-11 01:05:40 +00:00
|
|
|
ws.onmessage = (e) => {
|
|
|
|
if (!e.data) return;
|
|
|
|
try {
|
|
|
|
received(JSON.parse(e.data));
|
|
|
|
} catch(error) {
|
|
|
|
console.error(e);
|
2020-04-14 18:44:40 +00:00
|
|
|
console.error(`Could not parse the above streaming event.\n${error}`);
|
2020-04-11 01:05:40 +00:00
|
|
|
}
|
2020-04-14 18:44:40 +00:00
|
|
|
};
|
2020-04-11 01:05:40 +00:00
|
|
|
|
2020-03-27 20:59:38 +00:00
|
|
|
return ws;
|
|
|
|
};
|