2020-10-26 04:26:30 +03:00
|
|
|
import * as Window from "~/common/window";
|
2020-10-27 07:41:42 +03:00
|
|
|
import * as Strings from "~/common/strings";
|
2021-06-11 22:25:58 +03:00
|
|
|
import * as Logging from "~/common/logging";
|
2020-10-26 01:56:57 +03:00
|
|
|
|
2020-10-26 04:26:30 +03:00
|
|
|
let pingTimeout = null;
|
2020-10-26 01:56:57 +03:00
|
|
|
let client = null;
|
|
|
|
|
2021-01-11 06:57:40 +03:00
|
|
|
let savedResource = null;
|
|
|
|
let savedViewer = null;
|
|
|
|
let savedOnUpdate = null;
|
|
|
|
|
2021-02-09 12:56:24 +03:00
|
|
|
export const init = ({ resource = "", viewer, onUpdate, onNewActiveUser = () => {} }) => {
|
2021-01-11 06:57:40 +03:00
|
|
|
savedResource = resource;
|
|
|
|
savedViewer = viewer;
|
|
|
|
savedOnUpdate = onUpdate;
|
2020-11-26 02:19:02 +03:00
|
|
|
if (!process.browser) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-06-11 22:25:58 +03:00
|
|
|
Logging.log(`${resource}: init`);
|
2020-10-26 01:56:57 +03:00
|
|
|
|
2020-10-26 04:26:30 +03:00
|
|
|
if (client) {
|
2021-06-11 22:25:58 +03:00
|
|
|
Error.log("ERROR: Already has websocket client");
|
2020-10-26 04:26:30 +03:00
|
|
|
return client;
|
|
|
|
}
|
2020-10-26 01:56:57 +03:00
|
|
|
|
2020-10-26 04:26:30 +03:00
|
|
|
client = new WebSocket(resource);
|
|
|
|
|
|
|
|
client.addEventListener("open", (e) => {
|
|
|
|
if (!client) {
|
2020-11-26 02:19:02 +03:00
|
|
|
return null;
|
2020-10-26 04:26:30 +03:00
|
|
|
}
|
|
|
|
|
2021-03-07 23:53:54 +03:00
|
|
|
const payload = { type: "SUBSCRIBE_VIEWER", data: { id: viewer.id } };
|
2020-10-26 04:26:30 +03:00
|
|
|
client.send(JSON.stringify(payload));
|
|
|
|
});
|
|
|
|
|
|
|
|
client.addEventListener("ping", (e) => {
|
|
|
|
if (!client) {
|
2020-11-26 02:19:02 +03:00
|
|
|
return null;
|
2020-10-26 04:26:30 +03:00
|
|
|
}
|
|
|
|
|
2021-06-11 22:25:58 +03:00
|
|
|
Logging.log(`${resource}: ping`);
|
2020-10-26 04:26:30 +03:00
|
|
|
clearTimeout(pingTimeout);
|
|
|
|
|
|
|
|
pingTimeout = setTimeout(() => {
|
|
|
|
this.terminate();
|
|
|
|
}, 30000 + 1000);
|
|
|
|
});
|
|
|
|
|
2020-11-30 02:47:08 +03:00
|
|
|
client.addEventListener("message", function (event) {
|
2020-10-26 04:26:30 +03:00
|
|
|
if (!client) {
|
2020-11-26 02:19:02 +03:00
|
|
|
return null;
|
2020-10-26 04:26:30 +03:00
|
|
|
}
|
|
|
|
|
2020-10-27 07:41:42 +03:00
|
|
|
if (Strings.isEmpty(event.data)) {
|
2020-11-26 02:19:02 +03:00
|
|
|
return null;
|
2020-10-27 07:41:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
let type;
|
|
|
|
let data;
|
|
|
|
try {
|
|
|
|
const response = JSON.parse(event.data);
|
|
|
|
type = response.type;
|
|
|
|
data = response.data;
|
|
|
|
} catch (e) {
|
2021-06-11 22:25:58 +03:00
|
|
|
Logging.error(e);
|
2020-10-27 07:41:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!data) {
|
2020-11-26 02:19:02 +03:00
|
|
|
return null;
|
2020-10-27 07:41:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!type) {
|
2020-11-26 02:19:02 +03:00
|
|
|
return null;
|
2020-10-27 07:41:42 +03:00
|
|
|
}
|
|
|
|
|
2021-01-10 02:04:17 +03:00
|
|
|
if (type === "UPDATE") {
|
2021-05-06 03:08:14 +03:00
|
|
|
onUpdate({ viewer: data });
|
2020-10-27 07:41:42 +03:00
|
|
|
}
|
2021-02-04 12:21:59 +03:00
|
|
|
|
2021-02-09 12:56:24 +03:00
|
|
|
if (type === "UPDATE_USERS_ONLINE" && typeof onNewActiveUser === "function") {
|
2021-02-04 13:20:36 +03:00
|
|
|
onNewActiveUser(data);
|
2021-02-04 12:21:59 +03:00
|
|
|
}
|
2020-10-26 04:26:30 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
client.addEventListener("close", (e) => {
|
2021-04-07 01:08:42 +03:00
|
|
|
if (e.reason === "SIGN_OUT") {
|
2021-05-06 03:08:14 +03:00
|
|
|
window.location.replace("/_/auth");
|
2021-04-07 01:08:42 +03:00
|
|
|
} else {
|
|
|
|
setTimeout(() => {
|
|
|
|
client = null;
|
2021-06-11 22:25:58 +03:00
|
|
|
Logging.log("Auto reconnecting dropped websocket");
|
2021-04-07 01:08:42 +03:00
|
|
|
init({ resource, viewer, onUpdate });
|
|
|
|
}, 1000);
|
|
|
|
}
|
2020-10-26 04:26:30 +03:00
|
|
|
if (!client) {
|
2020-11-26 02:19:02 +03:00
|
|
|
return null;
|
2020-10-26 04:26:30 +03:00
|
|
|
}
|
|
|
|
|
2021-06-11 22:25:58 +03:00
|
|
|
Logging.log(`${resource}: closed`);
|
2020-10-26 04:26:30 +03:00
|
|
|
clearTimeout(pingTimeout);
|
|
|
|
});
|
2020-10-26 01:56:57 +03:00
|
|
|
|
|
|
|
return client;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const getClient = () => {
|
2020-11-26 02:19:02 +03:00
|
|
|
if (!process.browser) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-10-26 01:56:57 +03:00
|
|
|
return client;
|
|
|
|
};
|
2020-10-26 04:26:30 +03:00
|
|
|
|
|
|
|
export const deleteClient = async () => {
|
2020-11-26 02:19:02 +03:00
|
|
|
if (!process.browser) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-10-26 04:26:30 +03:00
|
|
|
if (!client) {
|
2021-06-11 22:25:58 +03:00
|
|
|
Logging.log("WEBSOCKET: NOTHING TO DELETE");
|
2020-10-26 04:26:30 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
clearTimeout(pingTimeout);
|
|
|
|
|
|
|
|
client.close();
|
|
|
|
client = null;
|
|
|
|
await Window.delay(0);
|
|
|
|
|
2021-06-11 22:25:58 +03:00
|
|
|
Logging.log("WEBSOCKET: TERMINATED");
|
2020-10-26 04:26:30 +03:00
|
|
|
|
|
|
|
return client;
|
|
|
|
};
|
2021-01-11 06:57:40 +03:00
|
|
|
|
|
|
|
export const checkWebsocket = async () => {
|
|
|
|
if (client) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!savedResource || !savedViewer || !savedOnUpdate) {
|
2021-06-11 22:25:58 +03:00
|
|
|
Logging.log("No saved resources from previous, so not connecting a websocket");
|
2021-01-11 06:57:40 +03:00
|
|
|
return;
|
|
|
|
}
|
2021-06-11 22:25:58 +03:00
|
|
|
Logging.log("Reconnecting dropped websocket");
|
2021-01-11 06:57:40 +03:00
|
|
|
init({ resource: savedResource, viewer: savedViewer, onUpdate: savedOnUpdate });
|
|
|
|
await Window.delay(2000);
|
|
|
|
return;
|
|
|
|
};
|