gab-social/app/javascript/gabsocial/stream.js

85 lines
2.0 KiB
JavaScript
Raw Normal View History

2019-07-02 08:10:25 +01: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() { } })) {
2019-07-02 08:10:25 +01:00
return (dispatch, getState) => {
const streamingAPIBaseURL = getState().getIn(['meta', 'streaming_api_base_url']);
const accessToken = getState().getIn(['meta', 'access_token']);
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, {
connected() {
2019-07-02 08:10:25 +01:00
if (pollingRefresh) {
clearPolling();
}
onConnect();
},
disconnected() {
2019-07-02 08:10:25 +01:00
if (pollingRefresh) {
polling = setTimeout(() => setupPolling(), randomIntUpTo(40000));
}
onDisconnect();
},
received(data) {
2019-07-02 08:10:25 +01:00
onReceive(data);
},
reconnected() {
2019-07-02 08:10:25 +01: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}`];
2019-07-02 08:10:25 +01:00
const ws = new WebSocketClient(`${streamingAPIBaseURL}/api/v1/streaming/?${params.join('&')}`, accessToken);
ws.onopen = connected;
ws.onmessage = e => received(JSON.parse(e.data));
ws.onclose = disconnected;
2019-07-02 08:10:25 +01:00
ws.onreconnect = reconnected;
return ws;
};