Showing
10 changed files
with
86 additions
and
124 deletions
1 | import { Socket } from "socket.io"; | 1 | import { Socket } from "socket.io"; |
2 | -import { ServerOutboundMessageMap } from "../../common"; | 2 | +import { ServerOutboundMessage, ServerOutboundMessageMap } from "../../common"; |
3 | -import { loginHandler } from "../message/handler/loginHandler"; | ||
4 | import { MessageHandlerChain } from "../message/MessageHandlerChain"; | 3 | import { MessageHandlerChain } from "../message/MessageHandlerChain"; |
5 | import { Room } from "../room/Room"; | 4 | import { Room } from "../room/Room"; |
6 | import { User } from "../user/User"; | 5 | import { User } from "../user/User"; |
... | @@ -19,7 +18,7 @@ export class Connection { | ... | @@ -19,7 +18,7 @@ export class Connection { |
19 | 18 | ||
20 | public send<T extends keyof ServerOutboundMessageMap>( | 19 | public send<T extends keyof ServerOutboundMessageMap>( |
21 | type: T, | 20 | type: T, |
22 | - message: ServerOutboundMessageMap[T] | 21 | + message: ServerOutboundMessage<T> |
23 | ) { | 22 | ) { |
24 | this.socket.emit(type as string, message); | 23 | this.socket.emit(type as string, message); |
25 | } | 24 | } | ... | ... |
... | @@ -4,33 +4,31 @@ import { | ... | @@ -4,33 +4,31 @@ import { |
4 | ServerInboundMessageMap, | 4 | ServerInboundMessageMap, |
5 | ServerResponse, | 5 | ServerResponse, |
6 | } from "../../common/index"; | 6 | } from "../../common/index"; |
7 | +import { User } from "../user/User"; | ||
7 | 8 | ||
8 | -type ServerHandlerMap<T> = { | 9 | +type UserHandlerMap = { |
9 | [Key in keyof ServerInboundMessageMap]?: ( | 10 | [Key in keyof ServerInboundMessageMap]?: ( |
10 | - connection: Connection, | 11 | + user: User, |
11 | - message: ServerInboundMessage<Key>, | 12 | + message: ServerInboundMessage<Key> |
12 | - scope: T | ||
13 | ) => ServerResponse<Key>; | 13 | ) => ServerResponse<Key>; |
14 | }; | 14 | }; |
15 | 15 | ||
16 | -export class HandlerMap<T> { | 16 | +export class MessageHandler { |
17 | - private scope: T; | 17 | + private handlers: UserHandlerMap; |
18 | - private handlers: ServerHandlerMap<T>; | ||
19 | 18 | ||
20 | - constructor(scope: T, handlers: ServerHandlerMap<T>) { | 19 | + constructor(handlers: UserHandlerMap) { |
21 | - this.scope = scope; | ||
22 | this.handlers = handlers; | 20 | this.handlers = handlers; |
23 | } | 21 | } |
24 | 22 | ||
25 | public handle( | 23 | public handle( |
26 | type: keyof ServerInboundMessageMap, | 24 | type: keyof ServerInboundMessageMap, |
27 | - connection: Connection, | 25 | + user: User, |
28 | message: any, | 26 | message: any, |
29 | callback: Function | 27 | callback: Function |
30 | ): boolean { | 28 | ): boolean { |
31 | const handler = this.handlers[type]; | 29 | const handler = this.handlers[type]; |
32 | if (!handler) return false; | 30 | if (!handler) return false; |
33 | - const response = handler(connection, message, this.scope); | 31 | + const response = handler(user, message); |
34 | callback(response); | 32 | callback(response); |
35 | return true; | 33 | return true; |
36 | } | 34 | } | ... | ... |
1 | import { Connection } from "../connection/Connection"; | 1 | import { Connection } from "../connection/Connection"; |
2 | -import { ServerInboundMessageMap, ServerResponse } from "../../common/index"; | 2 | +import { |
3 | + ServerInboundMessage, | ||
4 | + ServerInboundMessageMap, | ||
5 | + ServerResponse, | ||
6 | +} from "../../common/index"; | ||
3 | import { keys } from "ts-transformer-keys"; | 7 | import { keys } from "ts-transformer-keys"; |
4 | -import { HandlerMap } from "./MessageHandler"; | 8 | +import { User } from "../user/User"; |
5 | -import { loginHandler } from "./handler/loginHandler"; | ||
6 | 9 | ||
7 | export class MessageHandlerChain { | 10 | export class MessageHandlerChain { |
8 | connection: Connection; | 11 | connection: Connection; |
9 | 12 | ||
10 | - handler: HandlerMap<undefined>; | ||
11 | - | ||
12 | constructor(connection: Connection) { | 13 | constructor(connection: Connection) { |
13 | this.connection = connection; | 14 | this.connection = connection; |
14 | - this.handler = new HandlerMap(undefined, { | 15 | + |
15 | - login: loginHandler, | 16 | + // 유저 정보가 없으므로 로그인은 따로 핸들링 |
16 | - }); | 17 | + this.connection.socket.on( |
18 | + "login", | ||
19 | + (message: ServerInboundMessage<"login">, callback: Function) => { | ||
20 | + connection.user = new User(message.username, connection); | ||
21 | + console.log(`User ${message.username} has logged in!`); | ||
22 | + | ||
23 | + callback({ ok: true }); | ||
24 | + } | ||
25 | + ); | ||
17 | 26 | ||
18 | for (const key in keys<ServerInboundMessageMap>()) { | 27 | for (const key in keys<ServerInboundMessageMap>()) { |
19 | const type = key as keyof ServerInboundMessageMap; | 28 | const type = key as keyof ServerInboundMessageMap; |
20 | this.connection.socket.on(key, (message: any, callback: Function) => { | 29 | this.connection.socket.on(key, (message: any, callback: Function) => { |
30 | + // Game > Room > User 순으로 전달 | ||
21 | if ( | 31 | if ( |
22 | connection?.user?.room && | 32 | connection?.user?.room && |
23 | connection.user.room.handler.handle( | 33 | connection.user.room.handler.handle( |
24 | type, | 34 | type, |
25 | - connection, | 35 | + connection.user, |
26 | message, | 36 | message, |
27 | callback | 37 | callback |
28 | ) | 38 | ) |
... | @@ -31,11 +41,14 @@ export class MessageHandlerChain { | ... | @@ -31,11 +41,14 @@ export class MessageHandlerChain { |
31 | 41 | ||
32 | if ( | 42 | if ( |
33 | connection?.user && | 43 | connection?.user && |
34 | - connection.user.handler.handle(type, connection, message, callback) | 44 | + connection.user.handler.handle( |
45 | + type, | ||
46 | + connection.user, | ||
47 | + message, | ||
48 | + callback | ||
49 | + ) | ||
35 | ) | 50 | ) |
36 | return; | 51 | return; |
37 | - | ||
38 | - this.handler.handle(type, connection, message, callback); | ||
39 | }); | 52 | }); |
40 | } | 53 | } |
41 | } | 54 | } | ... | ... |
1 | -import { ServerInboundMessageMap, ServerResponse } from "../../../common"; | ||
2 | -import { Connection } from "../../connection/Connection"; | ||
3 | -import { RoomManager } from "../../room/RoomManager"; | ||
4 | -import { User } from "../../user/User"; | ||
5 | - | ||
6 | -export function loginHandler( | ||
7 | - connection: Connection, | ||
8 | - message: ServerInboundMessageMap["login"], | ||
9 | - scope: undefined | ||
10 | -): ServerResponse<"login"> { | ||
11 | - connection.user = new User(message.username, connection); | ||
12 | - console.log(`User ${message.username} has logged in!`); | ||
13 | - | ||
14 | - return { ok: true }; | ||
15 | -} |
1 | -import { ServerInboundMessage, ServerResponse } from "../../../common"; | ||
2 | -import { Connection } from "../../connection/Connection"; | ||
3 | -import { Room } from "../../room/Room"; | ||
4 | -import { RoomManager } from "../../room/RoomManager"; | ||
5 | -import { User } from "../../user/User"; | ||
6 | - | ||
7 | -export function chatHandler( | ||
8 | - connection: Connection, | ||
9 | - message: ServerInboundMessage<"chat">, | ||
10 | - scope: Room | ||
11 | -): ServerResponse<"chat"> { | ||
12 | - scope.sendChat(user, message.message); | ||
13 | - return { ok: true }; | ||
14 | -} |
1 | -import { ServerInboundMessage, ServerResponse } from "../../../common"; | ||
2 | -import { Connection } from "../../connection/Connection"; | ||
3 | -import { Room } from "../../room/Room"; | ||
4 | -import { RoomManager } from "../../room/RoomManager"; | ||
5 | -import { User } from "../../user/User"; | ||
6 | - | ||
7 | -export function roomJoinHandler( | ||
8 | - connection: Connection, | ||
9 | - message: ServerInboundMessage<"joinRoom">, | ||
10 | - scope: Room | ||
11 | -): ServerResponse<"joinRoom"> { | ||
12 | - const room = RoomManager.instance().get(message.uuid); | ||
13 | - if (room !== undefined) { | ||
14 | - room.connect(user); | ||
15 | - return { ok: user.room !== undefined, result: user.room?.getInfo() }; | ||
16 | - } | ||
17 | - return { ok: false }; | ||
18 | -} |
1 | -import { ServerInboundMessage, ServerResponse } from "../../../common"; | ||
2 | -import { Connection } from "../../connection/Connection"; | ||
3 | -import { Room } from "../../room/Room"; | ||
4 | -import { RoomManager } from "../../room/RoomManager"; | ||
5 | -import { User } from "../../user/User"; | ||
6 | - | ||
7 | -export function roomLeaveHandler( | ||
8 | - connection: Connection, | ||
9 | - message: ServerInboundMessage<"leaveRoom">, | ||
10 | - scope: Room | ||
11 | -): ServerResponse<"leaveRoom"> { | ||
12 | - user.room?.disconnect(user); | ||
13 | - return { ok: true }; | ||
14 | -} |
1 | -import { | ||
2 | - ServerInboundMessage, | ||
3 | - ServerInboundMessageMap, | ||
4 | - ServerResponse, | ||
5 | -} from "../../../common"; | ||
6 | -import { RoomDescription } from "../../../common/dataType"; | ||
7 | -import { Connection } from "../../connection/Connection"; | ||
8 | -import { RoomManager } from "../../room/RoomManager"; | ||
9 | -import { User } from "../../user/User"; | ||
10 | - | ||
11 | -export function roomListRequestHandler( | ||
12 | - connection: Connection, | ||
13 | - message: ServerInboundMessage<"roomList">, | ||
14 | - scope: User | ||
15 | -): ServerResponse<"roomList"> { | ||
16 | - return { ok: true, result: RoomManager.instance().list() }; | ||
17 | -} |
... | @@ -2,10 +2,13 @@ import { Connection } from "../connection/Connection"; | ... | @@ -2,10 +2,13 @@ import { Connection } from "../connection/Connection"; |
2 | import { v4 as uuidv4 } from "uuid"; | 2 | import { v4 as uuidv4 } from "uuid"; |
3 | import { User } from "../user/User"; | 3 | import { User } from "../user/User"; |
4 | import { MessageHandlerChain } from "../message/MessageHandlerChain"; | 4 | import { MessageHandlerChain } from "../message/MessageHandlerChain"; |
5 | -import { HandlerMap } from "../message/MessageHandler"; | 5 | +import { MessageHandler } from "../message/MessageHandler"; |
6 | -import { roomJoinHandler } from "../message/handler/roomJoinHandler"; | 6 | +import { |
7 | -import { roomLeaveHandler } from "../message/handler/roomLeaveHandler"; | 7 | + ServerInboundMessage, |
8 | -import { chatHandler } from "../message/handler/roomChatHandler"; | 8 | + ServerOutboundMessage, |
9 | + ServerOutboundMessageMap, | ||
10 | +} from "../../common"; | ||
11 | +import { RoomDescription, RoomInfo, UserData } from "../../common/dataType"; | ||
9 | 12 | ||
10 | export class Room { | 13 | export class Room { |
11 | public readonly uuid: string; | 14 | public readonly uuid: string; |
... | @@ -17,16 +20,22 @@ export class Room { | ... | @@ -17,16 +20,22 @@ export class Room { |
17 | 20 | ||
18 | private closed: boolean = false; | 21 | private closed: boolean = false; |
19 | 22 | ||
20 | - public handler: HandlerMap<Room>; | 23 | + public handler: MessageHandler; |
21 | 24 | ||
22 | constructor(name: string, maxUsers: number = 8) { | 25 | constructor(name: string, maxUsers: number = 8) { |
23 | this.uuid = uuidv4(); | 26 | this.uuid = uuidv4(); |
24 | this.name = name; | 27 | this.name = name; |
25 | this.maxUsers = maxUsers; | 28 | this.maxUsers = maxUsers; |
26 | - this.handler = new HandlerMap<Room>(this, { | 29 | + |
27 | - joinRoom: roomJoinHandler, | 30 | + this.handler = new MessageHandler({ |
28 | - leaveRoom: roomLeaveHandler, | 31 | + chat: (user, message) => { |
29 | - chat: chatHandler, | 32 | + this.sendChat(user, message.message); |
33 | + return { ok: true }; | ||
34 | + }, | ||
35 | + leaveRoom: (user, message) => { | ||
36 | + this.disconnect(user); | ||
37 | + return { ok: true }; | ||
38 | + }, | ||
30 | }); | 39 | }); |
31 | } | 40 | } |
32 | 41 | ||
... | @@ -35,10 +44,10 @@ export class Room { | ... | @@ -35,10 +44,10 @@ export class Room { |
35 | return; | 44 | return; |
36 | } | 45 | } |
37 | 46 | ||
38 | - this.broadcast(new RoomUserUpdateMessage("added", user.getData())); | 47 | + this.broadcast("updateRoomUser", { state: "added", user: user.getData() }); |
39 | 48 | ||
40 | this.users.push(user); | 49 | this.users.push(user); |
41 | - user.room = this; // TODO: 더 나은 관리 | 50 | + user.room = this; |
42 | } | 51 | } |
43 | 52 | ||
44 | public disconnect(user: User): void { | 53 | public disconnect(user: User): void { |
... | @@ -47,12 +56,15 @@ export class Room { | ... | @@ -47,12 +56,15 @@ export class Room { |
47 | this.users.splice(index, 1); | 56 | this.users.splice(index, 1); |
48 | user.room = undefined; | 57 | user.room = undefined; |
49 | 58 | ||
50 | - this.broadcast(new RoomUserUpdateMessage("removed", user.getData())); | 59 | + this.broadcast("updateRoomUser", { |
60 | + state: "removed", | ||
61 | + user: user.getData(), | ||
62 | + }); | ||
51 | } | 63 | } |
52 | } | 64 | } |
53 | 65 | ||
54 | public sendChat(user: User, message: string): void { | 66 | public sendChat(user: User, message: string): void { |
55 | - this.broadcast(new RoomChatMessage(message, user.username), user); | 67 | + this.broadcast("chat", { sender: user.username, message: message }); |
56 | } | 68 | } |
57 | 69 | ||
58 | public getDescription(): RoomDescription { | 70 | public getDescription(): RoomDescription { |
... | @@ -74,10 +86,14 @@ export class Room { | ... | @@ -74,10 +86,14 @@ export class Room { |
74 | }; | 86 | }; |
75 | } | 87 | } |
76 | 88 | ||
77 | - public broadcast(message: Message, except?: User): void { | 89 | + public broadcast<T extends keyof ServerOutboundMessageMap>( |
90 | + type: T, | ||
91 | + message: ServerOutboundMessage<T>, | ||
92 | + except?: User | ||
93 | + ): void { | ||
78 | this.users.forEach((u) => { | 94 | this.users.forEach((u) => { |
79 | if (u !== except) { | 95 | if (u !== except) { |
80 | - u.connection.send(message); | 96 | + u.connection.send(type, message); |
81 | } | 97 | } |
82 | }); | 98 | }); |
83 | } | 99 | } | ... | ... |
1 | import { UserData } from "../../common/dataType"; | 1 | import { UserData } from "../../common/dataType"; |
2 | import { Connection } from "../connection/Connection"; | 2 | import { Connection } from "../connection/Connection"; |
3 | -import { roomListRequestHandler } from "../message/handler/roomListRequestHandler"; | 3 | +import { MessageHandler } from "../message/MessageHandler"; |
4 | -import { HandlerMap } from "../message/MessageHandler"; | ||
5 | import { Room } from "../room/Room"; | 4 | import { Room } from "../room/Room"; |
5 | +import { RoomManager } from "../room/RoomManager"; | ||
6 | 6 | ||
7 | export class User { | 7 | export class User { |
8 | public readonly username: string; | 8 | public readonly username: string; |
... | @@ -11,13 +11,27 @@ export class User { | ... | @@ -11,13 +11,27 @@ export class User { |
11 | 11 | ||
12 | public room?: Room; | 12 | public room?: Room; |
13 | 13 | ||
14 | - public handler: HandlerMap<User>; | 14 | + public handler: MessageHandler; |
15 | 15 | ||
16 | constructor(username: string, connection: Connection) { | 16 | constructor(username: string, connection: Connection) { |
17 | this.username = username; | 17 | this.username = username; |
18 | this.connection = connection; | 18 | this.connection = connection; |
19 | - this.handler = new HandlerMap<User>(this, { | 19 | + this.handler = new MessageHandler({ |
20 | - roomList: roomListRequestHandler, | 20 | + roomList: (user, message) => { |
21 | + return { ok: true, result: RoomManager.instance().list() }; | ||
22 | + }, | ||
23 | + joinRoom: (user, message) => { | ||
24 | + const room = RoomManager.instance().get(message.uuid); | ||
25 | + if (user.room || !room) { | ||
26 | + return { ok: false }; | ||
27 | + } | ||
28 | + // TODO: 방 접속 실패 처리 | ||
29 | + room.connect(user); | ||
30 | + if (user.room === undefined) { | ||
31 | + return { ok: false }; | ||
32 | + } | ||
33 | + return { ok: true, result: room.getInfo() }; | ||
34 | + }, | ||
21 | }); | 35 | }); |
22 | } | 36 | } |
23 | 37 | ... | ... |
-
Please register or login to post a comment