Showing
5 changed files
with
30 additions
and
31 deletions
... | @@ -2,7 +2,9 @@ | ... | @@ -2,7 +2,9 @@ |
2 | 2 | ||
3 | 서버와의 통신은 socket.io를 사용합니다. | 3 | 서버와의 통신은 socket.io를 사용합니다. |
4 | 모든 메세지 interface들은 `server/message/types.ts`에 정의되어 있습니다. | 4 | 모든 메세지 interface들은 `server/message/types.ts`에 정의되어 있습니다. |
5 | -클라이언트에서 `emit`을 사용하여 전송한 모든 메세지에 대해 서버는 `MessageResponse`로 처리 결과를 알립니다. 자세한 사항은 https://socket.io/docs/v4/emitting-events/ 의 `Acknowledgements` 항목을 참조하세요. 요청이 성공하였을 때, 요청에 대한 결과 메세지가 해당 요청의 `MessageResponse`보다 먼저 도착할 수 있습니다 (확인 바람). | 5 | +클라이언트에서 `emit`을 사용하여 전송한 모든 메세지에 대해 서버는 `MessageResponse`로 처리 결과를 알립니다. 자세한 사항은 https://socket.io/docs/v4/emitting-events/ 의 `Acknowledgements` 항목을 참조하세요. 만약 요청에 대한 결과가 즉시 필요한 경우 `MessageResponse.result`로 결과가 전달됩니다. |
6 | + | ||
7 | +메세지 타입과 그에 대한 결과 타입은 `server/message/types.ts`를 참고하세요. | ||
6 | 8 | ||
7 | ## 로그인 | 9 | ## 로그인 |
8 | 10 | ||
... | @@ -12,12 +14,10 @@ | ... | @@ -12,12 +14,10 @@ |
12 | 14 | ||
13 | 로비에서는 모든 방 목록을 확인하고 접속할 수 있습니다. 로그인에 성공하면 서버에서 `RoomListMessage`가 전송됩니다. 이 메세지는 모든 방에 관한 정보를 가지고 있습니다. 각 방은 고유한 `uuid`값으로 구분됩니다. | 15 | 로비에서는 모든 방 목록을 확인하고 접속할 수 있습니다. 로그인에 성공하면 서버에서 `RoomListMessage`가 전송됩니다. 이 메세지는 모든 방에 관한 정보를 가지고 있습니다. 각 방은 고유한 `uuid`값으로 구분됩니다. |
14 | 16 | ||
15 | -특정한 방에 접속하기 위해서는 서버에 `RoomJoinMessage`를 보내면 됩니다. | 17 | +특정한 방에 접속하기 위해서는 서버에 `RoomJoinMessage`를 보내면 됩니다. 요청이 성공하면 `RoomInfo`가 반환됩니다. `RoomInfo`에는 본인을 제외한 다른 플레이어들의 정보만이 담겨 있습니다. |
16 | 18 | ||
17 | ### 방 | 19 | ### 방 |
18 | 20 | ||
19 | -방 접속에 성공하면 `RoomInfoMessage`가 수신됩니다. 이 메세지는 현재 방에 접속 중인 모든 유저의 정보를 가져옵니다. 모든 유저는 고유한 `username`을 가지므로, 앞으로 모든 메세지는 유저의 `username`만이 전송됩니다. | ||
20 | - | ||
21 | 방에 접속중인 유저의 목록에 변화가 생기면, `RoomUserUpdateMessage`가 수신됩니다. `state`는 다음 3가지 값 중 하나의 값을 가집니다. | 21 | 방에 접속중인 유저의 목록에 변화가 생기면, `RoomUserUpdateMessage`가 수신됩니다. `state`는 다음 3가지 값 중 하나의 값을 가집니다. |
22 | 22 | ||
23 | - `added`: 새로운 유저가 접속하였습니다. | 23 | - `added`: 새로운 유저가 접속하였습니다. | ... | ... |
... | @@ -26,10 +26,7 @@ export class MessageHandlerRegistry { | ... | @@ -26,10 +26,7 @@ export class MessageHandlerRegistry { |
26 | ); | 26 | ); |
27 | } | 27 | } |
28 | 28 | ||
29 | - private static registerHandler< | 29 | + private static registerHandler<T extends Message, S>( |
30 | - T extends Message, | ||
31 | - S extends Message | undefined | ||
32 | - >( | ||
33 | connection: Connection, | 30 | connection: Connection, |
34 | typeName: string, | 31 | typeName: string, |
35 | handler: (connection: Connection, message: T) => MessageResponse<S> | 32 | handler: (connection: Connection, message: T) => MessageResponse<S> |
... | @@ -40,10 +37,7 @@ export class MessageHandlerRegistry { | ... | @@ -40,10 +37,7 @@ export class MessageHandlerRegistry { |
40 | }); | 37 | }); |
41 | } | 38 | } |
42 | 39 | ||
43 | - private static registerHandlerAuthed< | 40 | + private static registerHandlerAuthed<T extends Message, S>( |
44 | - T extends Message, | ||
45 | - S extends Message | undefined | ||
46 | - >( | ||
47 | connection: Connection, | 41 | connection: Connection, |
48 | typeName: string, | 42 | typeName: string, |
49 | handler: (user: User, message: T) => MessageResponse<S> | 43 | handler: (user: User, message: T) => MessageResponse<S> | ... | ... |
1 | import { Connection } from "../../connection/Connection"; | 1 | import { Connection } from "../../connection/Connection"; |
2 | import { RoomManager } from "../../room/RoomManager"; | 2 | import { RoomManager } from "../../room/RoomManager"; |
3 | import { User } from "../../user/User"; | 3 | import { User } from "../../user/User"; |
4 | -import { MessageResponse, RoomInfoMessage, RoomJoinMessage } from "../types"; | 4 | +import { MessageResponse, RoomInfo, RoomJoinMessage } from "../types"; |
5 | 5 | ||
6 | export function roomJoinHandler( | 6 | export function roomJoinHandler( |
7 | user: User, | 7 | user: User, |
8 | message: RoomJoinMessage | 8 | message: RoomJoinMessage |
9 | -): MessageResponse<RoomInfoMessage> { | 9 | +): MessageResponse<RoomInfo> { |
10 | const room = RoomManager.instance().get(message.uuid); | 10 | const room = RoomManager.instance().get(message.uuid); |
11 | if (room !== undefined) { | 11 | if (room !== undefined) { |
12 | - const roomInfoMessage = room.connect(user); | 12 | + const roomInfo = room.connect(user); |
13 | - return { ok: roomInfoMessage !== undefined, result: roomInfoMessage }; | 13 | + return { ok: roomInfo !== undefined, result: roomInfo }; |
14 | } | 14 | } |
15 | return { ok: false }; | 15 | return { ok: false }; |
16 | } | 16 | } | ... | ... |
... | @@ -6,9 +6,17 @@ export interface Message { | ... | @@ -6,9 +6,17 @@ export interface Message { |
6 | } | 6 | } |
7 | 7 | ||
8 | /** | 8 | /** |
9 | + * 클라 -> 서버 : 클라이언트에서 서버로 요청할 때 사용하는 메세지입니다. 요청 결과는 MessageResponse<undefined>입니다. | ||
10 | + * 클라 -> 서버 -> T : 위와 동일하지만 요청 결과가 MessageResponse<T>입니다. | ||
11 | + * 서버 -> 클라 : 서버에서 클라이언트로 전송되는 메세지입니다. | ||
12 | + * 클라 <-> 서버 : 양방향으로 사용되는 메세지입니다. | ||
13 | + */ | ||
14 | + | ||
15 | +/** | ||
9 | * 서버에 Event를 보냈을 때 요청에 대한 결과를 전송받습니다. | 16 | * 서버에 Event를 보냈을 때 요청에 대한 결과를 전송받습니다. |
10 | * @param ok 요청의 성공 여부입니다. | 17 | * @param ok 요청의 성공 여부입니다. |
11 | * @param reason 요청 실패 사유입니다. 필요한 경우에만 포함됩니다. | 18 | * @param reason 요청 실패 사유입니다. 필요한 경우에만 포함됩니다. |
19 | + * @param result 요청에 대한 결과 메세지입니다. 특정한 메세지에 대해 요청이 성공하였을 때만 포함됩니다. | ||
12 | */ | 20 | */ |
13 | export interface MessageResponse<T> { | 21 | export interface MessageResponse<T> { |
14 | ok: boolean; | 22 | ok: boolean; |
... | @@ -35,7 +43,7 @@ export class RoomListMessage implements Message { | ... | @@ -35,7 +43,7 @@ export class RoomListMessage implements Message { |
35 | } | 43 | } |
36 | 44 | ||
37 | /** | 45 | /** |
38 | - * 클라 -> 서버 | 46 | + * 클라 -> 서버 -> RoomInfoMessage |
39 | * 방에 접속합니다. | 47 | * 방에 접속합니다. |
40 | */ | 48 | */ |
41 | export class RoomJoinMessage implements Message { | 49 | export class RoomJoinMessage implements Message { |
... | @@ -54,16 +62,6 @@ export class RoomLeaveMessage implements Message { | ... | @@ -54,16 +62,6 @@ export class RoomLeaveMessage implements Message { |
54 | 62 | ||
55 | /** | 63 | /** |
56 | * 클라 <- 서버 | 64 | * 클라 <- 서버 |
57 | - * 방에 접속할 때, 방의 정보를 받아옵니다. | ||
58 | - * @param userdata 현재 방에 접속 중인 유저 목록입니다. | ||
59 | - */ | ||
60 | -export class RoomInfoMessage implements Message { | ||
61 | - readonly type = MessageType.ROOM_INFO; | ||
62 | - constructor(public userdata: UserData[]) {} | ||
63 | -} | ||
64 | - | ||
65 | -/** | ||
66 | - * 클라 <- 서버 | ||
67 | * 접속한 방에 새로운 유저가 들어오거나 나갈 때 전송됩니다. | 65 | * 접속한 방에 새로운 유저가 들어오거나 나갈 때 전송됩니다. |
68 | * @param state 유저가 입장하면 added, 퇴장하면 removed 값을 가집니다. | 66 | * @param state 유저가 입장하면 added, 퇴장하면 removed 값을 가집니다. |
69 | * @param userdata 대상 유저입니다. | 67 | * @param userdata 대상 유저입니다. |
... | @@ -92,7 +90,14 @@ export class MessageType { | ... | @@ -92,7 +90,14 @@ export class MessageType { |
92 | static readonly ROOM_LIST = "room_list"; | 90 | static readonly ROOM_LIST = "room_list"; |
93 | static readonly ROOM_JOIN = "room_join"; | 91 | static readonly ROOM_JOIN = "room_join"; |
94 | static readonly ROOM_LEAVE = "room_leave"; | 92 | static readonly ROOM_LEAVE = "room_leave"; |
95 | - static readonly ROOM_INFO = "room_info"; | ||
96 | static readonly ROOM_USER_UPDATE = "room_user_update"; | 93 | static readonly ROOM_USER_UPDATE = "room_user_update"; |
97 | static readonly ROOM_CHAT = "room_chat"; | 94 | static readonly ROOM_CHAT = "room_chat"; |
98 | } | 95 | } |
96 | + | ||
97 | +/** | ||
98 | + * 방의 정보를 담고 있습니다. | ||
99 | + * @param userdata 현재 방에 접속 중인 유저 목록입니다. | ||
100 | + */ | ||
101 | +export interface RoomInfo { | ||
102 | + userdata: UserData[]; | ||
103 | +} | ... | ... |
... | @@ -4,7 +4,7 @@ import { RoomData } from "./types"; | ... | @@ -4,7 +4,7 @@ import { RoomData } from "./types"; |
4 | import { | 4 | import { |
5 | Message, | 5 | Message, |
6 | RoomChatMessage, | 6 | RoomChatMessage, |
7 | - RoomInfoMessage, | 7 | + RoomInfo, |
8 | RoomUserUpdateMessage, | 8 | RoomUserUpdateMessage, |
9 | } from "../message/types"; | 9 | } from "../message/types"; |
10 | import { UserData } from "../user/types"; | 10 | import { UserData } from "../user/types"; |
... | @@ -26,7 +26,7 @@ export class Room { | ... | @@ -26,7 +26,7 @@ export class Room { |
26 | this.maxUsers = maxUsers; | 26 | this.maxUsers = maxUsers; |
27 | } | 27 | } |
28 | 28 | ||
29 | - public connect(user: User): RoomInfoMessage | undefined { | 29 | + public connect(user: User): RoomInfo | undefined { |
30 | if (this.users.includes(user) || this.users.length >= this.maxUsers) { | 30 | if (this.users.includes(user) || this.users.length >= this.maxUsers) { |
31 | return undefined; | 31 | return undefined; |
32 | } | 32 | } |
... | @@ -42,7 +42,7 @@ export class Room { | ... | @@ -42,7 +42,7 @@ export class Room { |
42 | users.push(u.getData()); | 42 | users.push(u.getData()); |
43 | } | 43 | } |
44 | }); | 44 | }); |
45 | - return new RoomInfoMessage(users); | 45 | + return { userdata: users }; |
46 | } | 46 | } |
47 | 47 | ||
48 | public disconnect(user: User): void { | 48 | public disconnect(user: User): void { | ... | ... |
-
Please register or login to post a comment