2022-04-14 02:12:38 +03:00
|
|
|
import { getAuthToken, getItem } from "./storage";
|
|
|
|
|
|
|
|
export const GatewayPayloadType = {
|
|
|
|
Hello: 0,
|
|
|
|
Authenticate: 1,
|
|
|
|
Ready: 2,
|
|
|
|
Ping: 3,
|
|
|
|
|
|
|
|
ChannelCreate: 110,
|
|
|
|
ChannelUpdate: 111,
|
|
|
|
ChannelDelete: 112,
|
|
|
|
|
|
|
|
MessageCreate: 120,
|
|
|
|
MessageUpdate: 121,
|
|
|
|
MessageDelete: 122,
|
|
|
|
}
|
|
|
|
|
2022-04-17 04:08:40 +03:00
|
|
|
export const GatewayEventType = {
|
|
|
|
...GatewayPayloadType,
|
|
|
|
|
|
|
|
Open: -5,
|
|
|
|
Close: -4
|
|
|
|
}
|
|
|
|
|
2022-04-14 02:12:38 +03:00
|
|
|
export default {
|
|
|
|
ws: null,
|
|
|
|
authenticated: false,
|
|
|
|
heartbeatInterval: null,
|
|
|
|
user: null,
|
|
|
|
channels: null,
|
2022-04-14 16:56:01 +03:00
|
|
|
reconnectDelay: 400,
|
|
|
|
reconnectTimeout: null,
|
2022-04-17 04:08:40 +03:00
|
|
|
handlers: new Map(),
|
2022-04-14 02:12:38 +03:00
|
|
|
init() {
|
2022-04-17 04:08:40 +03:00
|
|
|
window.__WAFFLE_GATEWAY = this;
|
|
|
|
|
2022-04-14 16:56:01 +03:00
|
|
|
const token = getAuthToken();
|
|
|
|
if (!token) {
|
|
|
|
return false;
|
|
|
|
}
|
2022-04-14 02:12:38 +03:00
|
|
|
this.ws = new WebSocket(getItem("gatewayBase"));
|
2022-04-14 16:56:01 +03:00
|
|
|
this.ws.onopen = () => {
|
|
|
|
if (this.reconnectTimeout) {
|
|
|
|
clearTimeout(this.reconnectTimeout);
|
|
|
|
}
|
2022-04-17 04:08:40 +03:00
|
|
|
this.dispatch(GatewayEventType.Open, null);
|
2022-04-14 22:08:08 +03:00
|
|
|
console.log("[gateway] open");
|
2022-04-14 16:56:01 +03:00
|
|
|
};
|
|
|
|
this.ws.onmessage = (event) => {
|
|
|
|
const payload = JSON.parse(event.data);
|
2022-04-14 02:12:38 +03:00
|
|
|
|
|
|
|
switch (payload.t) {
|
|
|
|
case GatewayPayloadType.Hello: {
|
|
|
|
this.send({
|
|
|
|
t: GatewayPayloadType.Authenticate,
|
2022-04-14 16:56:01 +03:00
|
|
|
d: token
|
2022-04-14 02:12:38 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
this.heartbeatInterval = setInterval(() => {
|
|
|
|
this.send({
|
|
|
|
t: GatewayPayloadType.Ping,
|
|
|
|
d: 0
|
|
|
|
});
|
|
|
|
}, payload.d.pingInterval);
|
2022-04-14 22:08:08 +03:00
|
|
|
|
|
|
|
console.log("[gateway] hello");
|
2022-04-14 02:12:38 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GatewayPayloadType.Ready: {
|
|
|
|
this.user = payload.d.user;
|
|
|
|
this.channels = payload.d.channels;
|
2022-04-14 22:04:41 +03:00
|
|
|
|
|
|
|
this.reconnectDelay = 400;
|
2022-04-14 22:08:08 +03:00
|
|
|
|
|
|
|
console.log("[gateway] ready");
|
2022-04-14 02:12:38 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-04-17 04:08:40 +03:00
|
|
|
|
|
|
|
this.dispatch(payload.t, payload.d);
|
2022-04-14 02:12:38 +03:00
|
|
|
};
|
|
|
|
this.ws.onclose = () => {
|
2022-04-14 22:04:41 +03:00
|
|
|
if (this.reconnectDelay < 60000) {
|
|
|
|
this.reconnectDelay *= 2;
|
|
|
|
}
|
2022-04-14 02:12:38 +03:00
|
|
|
this.authenticated = false;
|
|
|
|
this.user = null;
|
|
|
|
this.channels = null;
|
|
|
|
if (this.heartbeatInterval) {
|
|
|
|
clearInterval(this.heartbeatInterval);
|
|
|
|
}
|
2022-04-14 16:56:01 +03:00
|
|
|
this.reconnectTimeout = setTimeout(() => {
|
|
|
|
this.init();
|
|
|
|
}, this.reconnectDelay);
|
2022-04-14 22:08:08 +03:00
|
|
|
|
2022-04-17 04:08:40 +03:00
|
|
|
this.dispatch(GatewayEventType.Close, null);
|
|
|
|
|
2022-04-14 22:08:08 +03:00
|
|
|
console.log("[gateway] close");
|
2022-04-14 02:12:38 +03:00
|
|
|
};
|
2022-04-14 16:56:01 +03:00
|
|
|
|
|
|
|
return true;
|
2022-04-14 02:12:38 +03:00
|
|
|
},
|
|
|
|
send(data) {
|
|
|
|
return this.ws.send(JSON.stringify(data));
|
2022-04-17 04:08:40 +03:00
|
|
|
},
|
|
|
|
dispatch(event, payload) {
|
|
|
|
const eventHandlers = this.handlers.get(event);
|
|
|
|
if (!eventHandlers)
|
|
|
|
return;
|
|
|
|
|
|
|
|
eventHandlers.forEach((e) => {
|
|
|
|
e(payload);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
subscribe(event, handler) {
|
|
|
|
if (!this.handlers.get(event)) {
|
|
|
|
this.handlers.set(event, new Set());
|
|
|
|
}
|
|
|
|
|
|
|
|
this.handlers.get(event).add(handler);
|
|
|
|
return handler; // can later be used for unsubscribe()
|
|
|
|
},
|
|
|
|
unsubscribe(event, handler) {
|
|
|
|
const eventHandlers = this.handlers.get(event);
|
|
|
|
if (!eventHandlers)
|
|
|
|
return;
|
|
|
|
|
|
|
|
eventHandlers.delete(handler);
|
|
|
|
|
|
|
|
if (eventHandlers.size < 1) {
|
|
|
|
this.handlers.delete(event);
|
|
|
|
}
|
2022-04-14 02:12:38 +03:00
|
|
|
}
|
|
|
|
};
|