Showing
6 changed files
with
82 additions
and
66 deletions
| 1 | import { Socket } from "socket.io"; | 1 | import { Socket } from "socket.io"; |
| 2 | -import { MessageHandlerRegistry } from "../message/MessageHandlerRegistry"; | 2 | +import { ServerOutboundMessageMap } from "../../common"; |
| 3 | -import { Message } from "../message/types"; | 3 | +import { loginHandler } from "../message/handler/loginHandler"; |
| 4 | +import { MessageHandlerChain } from "../message/MessageHandlerChain"; | ||
| 4 | import { Room } from "../room/Room"; | 5 | import { Room } from "../room/Room"; |
| 5 | import { User } from "../user/User"; | 6 | import { User } from "../user/User"; |
| 6 | 7 | ||
| ... | @@ -9,17 +10,21 @@ export class Connection { | ... | @@ -9,17 +10,21 @@ export class Connection { |
| 9 | 10 | ||
| 10 | public user?: User; | 11 | public user?: User; |
| 11 | 12 | ||
| 13 | + private messageHandlerChain: MessageHandlerChain; | ||
| 14 | + | ||
| 12 | constructor(socket: Socket) { | 15 | constructor(socket: Socket) { |
| 13 | this.socket = socket; | 16 | this.socket = socket; |
| 14 | - | 17 | + this.messageHandlerChain = new MessageHandlerChain(this); |
| 15 | - MessageHandlerRegistry.registerHandlers(this); | ||
| 16 | } | 18 | } |
| 17 | 19 | ||
| 18 | public get authenticated(): boolean { | 20 | public get authenticated(): boolean { |
| 19 | return this.user !== undefined; | 21 | return this.user !== undefined; |
| 20 | } | 22 | } |
| 21 | 23 | ||
| 22 | - public send(message: Message) { | 24 | + public send<T extends keyof ServerOutboundMessageMap>( |
| 23 | - this.socket.emit(message.type, message); | 25 | + type: T, |
| 26 | + message: ServerOutboundMessageMap[T] | ||
| 27 | + ) { | ||
| 28 | + this.socket.emit(type as string, message); | ||
| 24 | } | 29 | } |
| 25 | } | 30 | } | ... | ... |
server/message/MessageHandler.ts
0 → 100644
| 1 | +import { Connection } from "../connection/Connection"; | ||
| 2 | +import { ServerInboundMessageMap, ServerResponse } from "../../common/index"; | ||
| 3 | + | ||
| 4 | +type ServerHandlerMap<T> = { | ||
| 5 | + [Key in keyof ServerInboundMessageMap]?: ( | ||
| 6 | + connection: Connection, | ||
| 7 | + message: Omit<ServerInboundMessageMap[Key], "result">, | ||
| 8 | + scope: T | ||
| 9 | + ) => ServerResponse< | ||
| 10 | + "result" extends keyof ServerInboundMessageMap[Key] | ||
| 11 | + ? ServerInboundMessageMap[Key]["result"] | ||
| 12 | + : undefined | ||
| 13 | + >; | ||
| 14 | +}; | ||
| 15 | + | ||
| 16 | +export class HandlerMap<T> { | ||
| 17 | + private scope: T; | ||
| 18 | + private handlers: ServerHandlerMap<T>; | ||
| 19 | + | ||
| 20 | + constructor(scope: T, handlers: ServerHandlerMap<T>) { | ||
| 21 | + this.scope = scope; | ||
| 22 | + this.handlers = handlers; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public handle( | ||
| 26 | + type: keyof ServerInboundMessageMap, | ||
| 27 | + connection: Connection, | ||
| 28 | + message: any, | ||
| 29 | + callback: Function | ||
| 30 | + ): boolean { | ||
| 31 | + const handler = this.handlers[type]; | ||
| 32 | + if (!handler) return false; | ||
| 33 | + const response = handler(connection, message, this.scope); | ||
| 34 | + callback(response); | ||
| 35 | + return true; | ||
| 36 | + } | ||
| 37 | +} |
server/message/MessageHandlerChain.ts
0 → 100644
| 1 | +import { Connection } from "../connection/Connection"; | ||
| 2 | +import { ServerInboundMessageMap, ServerResponse } from "../../common/index"; | ||
| 3 | +import { keys } from "ts-transformer-keys"; | ||
| 4 | + | ||
| 5 | +export class MessageHandlerChain { | ||
| 6 | + connection: Connection; | ||
| 7 | + | ||
| 8 | + constructor(connection: Connection) { | ||
| 9 | + this.connection = connection; | ||
| 10 | + | ||
| 11 | + for (const key in keys<ServerInboundMessageMap>()) { | ||
| 12 | + const type = key as keyof ServerInboundMessageMap; | ||
| 13 | + this.connection.socket.on(key, (message: any, callback: Function) => { | ||
| 14 | + if ( | ||
| 15 | + connection?.user && | ||
| 16 | + connection.user.handler.handle( | ||
| 17 | + type, | ||
| 18 | + connection, | ||
| 19 | + message.data, | ||
| 20 | + callback | ||
| 21 | + ) | ||
| 22 | + ) | ||
| 23 | + return; | ||
| 24 | + | ||
| 25 | + // TODO: Add more handlers | ||
| 26 | + }); | ||
| 27 | + } | ||
| 28 | + } | ||
| 29 | +} |
| 1 | -import { Connection } from "../connection/Connection"; | ||
| 2 | -import { User } from "../user/User"; | ||
| 3 | -import { loginHandler } from "./handler/loginHandler"; | ||
| 4 | -import { roomChatHandler } from "./handler/roomChatHandler"; | ||
| 5 | -import { roomJoinHandler } from "./handler/roomJoinHandler"; | ||
| 6 | -import { roomLeaveHandler } from "./handler/roomLeaveHandler"; | ||
| 7 | -import { roomListRequestHandler } from "./handler/roomListRequestHandler"; | ||
| 8 | -import { Message, MessageResponse, MessageType } from "./types"; | ||
| 9 | - | ||
| 10 | -export class MessageHandlerRegistry { | ||
| 11 | - static registerHandlers(connection: Connection) { | ||
| 12 | - this.registerHandler(connection, MessageType.LOGIN, loginHandler); | ||
| 13 | - this.registerHandlerAuthed( | ||
| 14 | - connection, | ||
| 15 | - MessageType.ROOM_LIST_REQUEST, | ||
| 16 | - roomListRequestHandler | ||
| 17 | - ); | ||
| 18 | - this.registerHandlerAuthed( | ||
| 19 | - connection, | ||
| 20 | - MessageType.ROOM_JOIN, | ||
| 21 | - roomJoinHandler | ||
| 22 | - ); | ||
| 23 | - this.registerHandlerAuthed( | ||
| 24 | - connection, | ||
| 25 | - MessageType.ROOM_LEAVE, | ||
| 26 | - roomLeaveHandler | ||
| 27 | - ); | ||
| 28 | - this.registerHandlerAuthed( | ||
| 29 | - connection, | ||
| 30 | - MessageType.ROOM_CHAT, | ||
| 31 | - roomChatHandler | ||
| 32 | - ); | ||
| 33 | - } | ||
| 34 | - | ||
| 35 | - private static registerHandler<T extends Message, S>( | ||
| 36 | - connection: Connection, | ||
| 37 | - typeName: string, | ||
| 38 | - handler: (connection: Connection, message: T) => MessageResponse<S> | ||
| 39 | - ) { | ||
| 40 | - connection.socket.on(typeName, (message: T, callback: Function) => { | ||
| 41 | - const response = handler(connection, message); | ||
| 42 | - callback(response); | ||
| 43 | - }); | ||
| 44 | - } | ||
| 45 | - | ||
| 46 | - private static registerHandlerAuthed<T extends Message, S>( | ||
| 47 | - connection: Connection, | ||
| 48 | - typeName: string, | ||
| 49 | - handler: (user: User, message: T) => MessageResponse<S> | ||
| 50 | - ) { | ||
| 51 | - connection.socket.on(typeName, (message: T, callback: Function) => { | ||
| 52 | - if (connection.user !== undefined) { | ||
| 53 | - const response = handler(connection.user, message); | ||
| 54 | - callback(response); | ||
| 55 | - } else { | ||
| 56 | - callback({ ok: false }); | ||
| 57 | - } | ||
| 58 | - }); | ||
| 59 | - } | ||
| 60 | -} |
| 1 | import { Connection } from "../connection/Connection"; | 1 | import { Connection } from "../connection/Connection"; |
| 2 | +import { HandlerMap } from "../message/MessageHandler"; | ||
| 2 | import { Room } from "../room/Room"; | 3 | import { Room } from "../room/Room"; |
| 3 | import { UserData } from "./types"; | 4 | import { UserData } from "./types"; |
| 4 | 5 | ||
| ... | @@ -9,9 +10,12 @@ export class User { | ... | @@ -9,9 +10,12 @@ export class User { |
| 9 | 10 | ||
| 10 | public room?: Room; | 11 | public room?: Room; |
| 11 | 12 | ||
| 13 | + public handler: HandlerMap<User>; | ||
| 14 | + | ||
| 12 | constructor(username: string, connection: Connection) { | 15 | constructor(username: string, connection: Connection) { |
| 13 | this.username = username; | 16 | this.username = username; |
| 14 | this.connection = connection; | 17 | this.connection = connection; |
| 18 | + this.handler = new HandlerMap<User>(this, {}); | ||
| 15 | } | 19 | } |
| 16 | 20 | ||
| 17 | public getData(): UserData { | 21 | public getData(): UserData { | ... | ... |
-
Please register or login to post a comment