66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
import { Room, RoomServerMessage, RoomMessage } from "./store/room";
|
|
|
|
export interface RoomConnectionData {
|
|
ws_url: string;
|
|
auth_token: string;
|
|
}
|
|
|
|
export type MessageHandler = (msg: RoomServerMessage) => void;
|
|
|
|
export default class RoomClient {
|
|
private ws: WebSocket;
|
|
public info: Room;
|
|
|
|
private onMessage?: MessageHandler;
|
|
private buffer: RoomServerMessage[];
|
|
|
|
constructor(_ws: WebSocket, _info: Room) {
|
|
this.info = _info;
|
|
this.buffer = [];
|
|
this.ws = _ws;
|
|
this.ws.addEventListener("message", this._received.bind(this));
|
|
}
|
|
|
|
private _received(ev: MessageEvent) {
|
|
let data = JSON.parse(ev.data);
|
|
if (this.onMessage) {
|
|
return this.onMessage(data);
|
|
}
|
|
// Save messages in a buffer if no handler is set
|
|
this.buffer.push(data);
|
|
}
|
|
|
|
public setMessageHandler(handler: MessageHandler) {
|
|
// Set as handler for all future messages
|
|
this.onMessage = handler;
|
|
// If we have messages in our buffer, send them over
|
|
for (const msg of this.buffer) {
|
|
handler(msg);
|
|
}
|
|
// Empty buffer
|
|
this.buffer = [];
|
|
}
|
|
|
|
public static connect(wsdata: RoomConnectionData): Promise<RoomClient> {
|
|
return new Promise((resolve, reject) => {
|
|
let ws = new WebSocket(wsdata.ws_url);
|
|
const onMessage = (ev: MessageEvent) => {
|
|
// Unregister handler
|
|
ws.removeEventListener("message", onMessage);
|
|
// Parse message
|
|
let data = JSON.parse(ev.data);
|
|
if ("error" in data) {
|
|
reject(data.error);
|
|
}
|
|
let client = new RoomClient(ws, data.event.room);
|
|
resolve(client);
|
|
};
|
|
ws.addEventListener("message", onMessage);
|
|
ws.addEventListener("open", ev => {
|
|
// Send authentication
|
|
ws.send(JSON.stringify({ token: wsdata.auth_token }));
|
|
});
|
|
});
|
|
}
|
|
}
|