Refactored messaging system. Now messages about room state sent from user and server are same. Added "broadcasting" of room state update

This commit is contained in:
Dmitriy Shishkov 2021-09-04 16:46:50 +03:00
parent d10f1ece0f
commit f2057e96f8
No known key found for this signature in database
GPG Key ID: 14358F96FCDD8060
4 changed files with 43 additions and 29 deletions

View File

@ -1,27 +1,27 @@
import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class Room {
export abstract class Room {
@PrimaryGeneratedColumn()
id: number;
abstract id: number;
@Column({
length: 100,
})
title: string;
abstract title: string;
@Column()
free: boolean;
abstract free: boolean;
@Column()
x: number;
abstract x: number;
@Column()
y: number;
abstract y: number;
@Column()
width: number;
abstract width: number;
@Column()
height: number;
abstract height: number;
}

View File

@ -1,9 +1,9 @@
import "reflect-metadata";
import { Server } from "ws";
import { Server, OPEN } from "ws";
import { connect, getRoomList, updateFree } from "./db";
import { isIdMessage, isMessage } from "./types";
import { isMessage, isUpdateMessage } from "./types";
(async () => {
const main = async () => {
const connection = await connect();
const wss = new Server({
@ -13,12 +13,25 @@ import { isIdMessage, isMessage } from "./types";
wss.on("connection", async (ws) => {
ws.send(JSON.stringify(await getRoomList(connection)));
ws.on("message", (data) => {
const message: unknown = JSON.parse(data.toString());
if (!isMessage(message)) throw new Error("Message corrupted");
ws.on("message", async (data) => {
try {
const message: unknown = JSON.parse(data.toString());
if (!isMessage(message)) throw new Error("Message corrupted");
if (isIdMessage(message))
updateFree(connection, message.args.id, message.type === "freed");
if (isUpdateMessage(message)) {
const { id, value } = message.args;
await updateFree(connection, id, value);
wss.clients.forEach((client) => {
if (client.readyState === OPEN)
client.send(JSON.stringify(message));
});
}
} catch (err) {
console.log("Error processing message", err);
}
});
});
})();
};
main();

View File

@ -1,32 +1,33 @@
import { idMsgTypes } from "./constants";
export type IdMsgTypes = typeof idMsgTypes[number];
export type Message = {
type: string;
args: unknown;
};
export type IdMessage = Message & {
type: IdMsgTypes;
export type UpdateMessage = Message & {
type: "update";
args: {
id: number;
value: boolean;
};
};
const isObjLike = (obj: unknown): obj is object =>
Boolean(obj) && typeof obj === "object";
const hasProperty = <T extends {}, U extends PropertyKey>(
obj: T,
prop: U
): obj is T & Record<U, unknown> => prop in obj;
export const isMessage = (obj: unknown): obj is Message =>
typeof obj === "object" &&
isObjLike(obj) &&
hasProperty(obj, "type") &&
typeof obj.type === "string" &&
hasProperty(obj, "args");
export const isIdMessage = (message: Message): message is IdMessage =>
idMsgTypes.reduce((prev, curr) => prev || curr === message.type, false) &&
typeof message.args === "object" &&
export const isUpdateMessage = (message: Message): message is UpdateMessage =>
isObjLike(message.args) &&
hasProperty(message.args, "id") &&
typeof message.args.id === "number";
typeof message.args.id === "number" &&
hasProperty(message.args, "value") &&
typeof message.args.value === "boolean";

View File

@ -5,7 +5,7 @@
"esModuleInterop": true,
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true,
"strict": false,
"strict": true,
"skipLibCheck": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,