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:
parent
d10f1ece0f
commit
f2057e96f8
@ -1,27 +1,27 @@
|
|||||||
import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";
|
import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class Room {
|
export abstract class Room {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id: number;
|
abstract id: number;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
length: 100,
|
length: 100,
|
||||||
})
|
})
|
||||||
title: string;
|
abstract title: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
free: boolean;
|
abstract free: boolean;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
x: number;
|
abstract x: number;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
y: number;
|
abstract y: number;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
width: number;
|
abstract width: number;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
height: number;
|
abstract height: number;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import "reflect-metadata";
|
import "reflect-metadata";
|
||||||
import { Server } from "ws";
|
import { Server, OPEN } from "ws";
|
||||||
import { connect, getRoomList, updateFree } from "./db";
|
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 connection = await connect();
|
||||||
|
|
||||||
const wss = new Server({
|
const wss = new Server({
|
||||||
@ -13,12 +13,25 @@ import { isIdMessage, isMessage } from "./types";
|
|||||||
wss.on("connection", async (ws) => {
|
wss.on("connection", async (ws) => {
|
||||||
ws.send(JSON.stringify(await getRoomList(connection)));
|
ws.send(JSON.stringify(await getRoomList(connection)));
|
||||||
|
|
||||||
ws.on("message", (data) => {
|
ws.on("message", async (data) => {
|
||||||
const message: unknown = JSON.parse(data.toString());
|
try {
|
||||||
if (!isMessage(message)) throw new Error("Message corrupted");
|
const message: unknown = JSON.parse(data.toString());
|
||||||
|
if (!isMessage(message)) throw new Error("Message corrupted");
|
||||||
|
|
||||||
if (isIdMessage(message))
|
if (isUpdateMessage(message)) {
|
||||||
updateFree(connection, message.args.id, message.type === "freed");
|
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();
|
||||||
|
@ -1,32 +1,33 @@
|
|||||||
import { idMsgTypes } from "./constants";
|
|
||||||
|
|
||||||
export type IdMsgTypes = typeof idMsgTypes[number];
|
|
||||||
|
|
||||||
export type Message = {
|
export type Message = {
|
||||||
type: string;
|
type: string;
|
||||||
args: unknown;
|
args: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IdMessage = Message & {
|
export type UpdateMessage = Message & {
|
||||||
type: IdMsgTypes;
|
type: "update";
|
||||||
args: {
|
args: {
|
||||||
id: number;
|
id: number;
|
||||||
|
value: boolean;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isObjLike = (obj: unknown): obj is object =>
|
||||||
|
Boolean(obj) && typeof obj === "object";
|
||||||
|
|
||||||
const hasProperty = <T extends {}, U extends PropertyKey>(
|
const hasProperty = <T extends {}, U extends PropertyKey>(
|
||||||
obj: T,
|
obj: T,
|
||||||
prop: U
|
prop: U
|
||||||
): obj is T & Record<U, unknown> => prop in obj;
|
): obj is T & Record<U, unknown> => prop in obj;
|
||||||
|
|
||||||
export const isMessage = (obj: unknown): obj is Message =>
|
export const isMessage = (obj: unknown): obj is Message =>
|
||||||
typeof obj === "object" &&
|
isObjLike(obj) &&
|
||||||
hasProperty(obj, "type") &&
|
hasProperty(obj, "type") &&
|
||||||
typeof obj.type === "string" &&
|
typeof obj.type === "string" &&
|
||||||
hasProperty(obj, "args");
|
hasProperty(obj, "args");
|
||||||
|
|
||||||
export const isIdMessage = (message: Message): message is IdMessage =>
|
export const isUpdateMessage = (message: Message): message is UpdateMessage =>
|
||||||
idMsgTypes.reduce((prev, curr) => prev || curr === message.type, false) &&
|
isObjLike(message.args) &&
|
||||||
typeof message.args === "object" &&
|
|
||||||
hasProperty(message.args, "id") &&
|
hasProperty(message.args, "id") &&
|
||||||
typeof message.args.id === "number";
|
typeof message.args.id === "number" &&
|
||||||
|
hasProperty(message.args, "value") &&
|
||||||
|
typeof message.args.value === "boolean";
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"strict": false,
|
"strict": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user