Showing
6 changed files
with
138 additions
and
136 deletions
| 1 | import { RoomDescription, RoomInfo } from "./dataType"; | 1 | import { RoomDescription, RoomInfo } from "./dataType"; |
| 2 | -import { keys } from "ts-transformer-keys"; | ||
| 3 | 2 | ||
| 4 | // 서버로 들어오는 메세지 타입을 정의합니다. | 3 | // 서버로 들어오는 메세지 타입을 정의합니다. |
| 5 | // 'result' 속성은 서버 요청 결과에만 포함되는 특별한 속성입니다. | 4 | // 'result' 속성은 서버 요청 결과에만 포함되는 특별한 속성입니다. |
| ... | @@ -122,9 +121,12 @@ interface ServerOutboundMessageMap { | ... | @@ -122,9 +121,12 @@ interface ServerOutboundMessageMap { |
| 122 | }; | 121 | }; |
| 123 | } | 122 | } |
| 124 | 123 | ||
| 125 | -export type ServerInboundMessageKey = keyof ServerInboundMessageMap; | 124 | +export interface RawMessage { |
| 125 | + type: string; | ||
| 126 | + message: any; | ||
| 127 | +} | ||
| 126 | 128 | ||
| 127 | -export const ServerInboundMessageKeyArray = keys<ServerInboundMessageMap>(); | 129 | +export type ServerInboundMessageKey = keyof ServerInboundMessageMap; |
| 128 | 130 | ||
| 129 | export type ServerInboundMessage<Key extends ServerInboundMessageKey> = Omit< | 131 | export type ServerInboundMessage<Key extends ServerInboundMessageKey> = Omit< |
| 130 | ServerInboundMessageMap[Key], | 132 | ServerInboundMessageMap[Key], |
| ... | @@ -143,5 +145,3 @@ export type ServerOutboundMessage<Key extends keyof ServerOutboundMessageMap> = | ... | @@ -143,5 +145,3 @@ export type ServerOutboundMessage<Key extends keyof ServerOutboundMessageMap> = |
| 143 | ServerOutboundMessageMap[Key]; | 145 | ServerOutboundMessageMap[Key]; |
| 144 | 146 | ||
| 145 | export type ServerOutboundMessageKey = keyof ServerOutboundMessageMap; | 147 | export type ServerOutboundMessageKey = keyof ServerOutboundMessageMap; |
| 146 | - | ||
| 147 | -export const ServerOutboundMessageKeyArray = keys<ServerOutboundMessageMap>(); | ... | ... |
| ... | @@ -2,7 +2,3 @@ | ... | @@ -2,7 +2,3 @@ |
| 2 | # yarn lockfile v1 | 2 | # yarn lockfile v1 |
| 3 | 3 | ||
| 4 | 4 | ||
| 5 | -ts-transformer-keys@^0.4.3: | ||
| 6 | - version "0.4.3" | ||
| 7 | - resolved "https://registry.yarnpkg.com/ts-transformer-keys/-/ts-transformer-keys-0.4.3.tgz#d62389a40f430c00ef98fb9575fb6778a196e3ed" | ||
| 8 | - integrity sha512-pOTLlet1SnAvhKNr9tMAFwuv5283OkUNiq1fXTEK+vrSv+kxU3e2Ijr/UkqyX2vuMmvcNHdpXC31hob7ljH//g== | ... | ... |
| ... | @@ -20,6 +20,9 @@ export class Connection { | ... | @@ -20,6 +20,9 @@ export class Connection { |
| 20 | type: T, | 20 | type: T, |
| 21 | message: ServerOutboundMessage<T> | 21 | message: ServerOutboundMessage<T> |
| 22 | ) { | 22 | ) { |
| 23 | - this.socket.emit(type as string, message); | 23 | + this.socket.emit("msg", { |
| 24 | + type: type as string, | ||
| 25 | + message: message, | ||
| 26 | + }); | ||
| 24 | } | 27 | } |
| 25 | } | 28 | } | ... | ... |
| 1 | import { Connection } from "../connection/Connection"; | 1 | import { Connection } from "../connection/Connection"; |
| 2 | import { | 2 | import { |
| 3 | + RawMessage, | ||
| 3 | ServerInboundMessage, | 4 | ServerInboundMessage, |
| 4 | ServerInboundMessageKey, | 5 | ServerInboundMessageKey, |
| 5 | - ServerOutboundMessageKeyArray, | ||
| 6 | ServerResponse, | 6 | ServerResponse, |
| 7 | } from "../../common/index"; | 7 | } from "../../common/index"; |
| 8 | import { User } from "../user/User"; | 8 | import { User } from "../user/User"; |
| ... | @@ -13,43 +13,52 @@ export class MessageHandlerChain { | ... | @@ -13,43 +13,52 @@ export class MessageHandlerChain { |
| 13 | constructor(connection: Connection) { | 13 | constructor(connection: Connection) { |
| 14 | this.connection = connection; | 14 | this.connection = connection; |
| 15 | 15 | ||
| 16 | + this.connection.socket.on("msg", (raw: RawMessage, callback: Function) => { | ||
| 17 | + this.handleRaw(connection, raw, callback); | ||
| 18 | + }); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + private handleRaw( | ||
| 22 | + connection: Connection, | ||
| 23 | + raw: RawMessage, | ||
| 24 | + callback: Function | ||
| 25 | + ) { | ||
| 26 | + const type = raw.type as ServerInboundMessageKey; | ||
| 27 | + const message = raw.message; | ||
| 28 | + | ||
| 16 | // 유저 정보가 없으므로 로그인은 따로 핸들링 | 29 | // 유저 정보가 없으므로 로그인은 따로 핸들링 |
| 17 | - this.connection.socket.on( | 30 | + if (type === "login") { |
| 18 | - "login", | 31 | + this.handleLogin(connection, message, callback); |
| 19 | - (message: ServerInboundMessage<"login">, callback: Function) => { | 32 | + return; |
| 20 | - connection.user = new User(message.username, connection); | ||
| 21 | - console.log(`User ${message.username} has logged in!`); | ||
| 22 | - | ||
| 23 | - callback({ ok: true }); | ||
| 24 | - } | ||
| 25 | - ); | ||
| 26 | - | ||
| 27 | - for (const key in ServerOutboundMessageKeyArray) { | ||
| 28 | - const type = key as ServerInboundMessageKey; | ||
| 29 | - this.connection.socket.on(key, (message: any, callback: Function) => { | ||
| 30 | - // Game > Room > User 순으로 전달 | ||
| 31 | - if ( | ||
| 32 | - connection?.user?.room && | ||
| 33 | - connection.user.room.handler.handle( | ||
| 34 | - type, | ||
| 35 | - connection.user, | ||
| 36 | - message, | ||
| 37 | - callback | ||
| 38 | - ) | ||
| 39 | - ) | ||
| 40 | - return; | ||
| 41 | - | ||
| 42 | - if ( | ||
| 43 | - connection?.user && | ||
| 44 | - connection.user.handler.handle( | ||
| 45 | - type, | ||
| 46 | - connection.user, | ||
| 47 | - message, | ||
| 48 | - callback | ||
| 49 | - ) | ||
| 50 | - ) | ||
| 51 | - return; | ||
| 52 | - }); | ||
| 53 | } | 33 | } |
| 34 | + | ||
| 35 | + // Game > Room > User 순으로 전달 | ||
| 36 | + if ( | ||
| 37 | + connection?.user?.room && | ||
| 38 | + connection.user.room.handler.handle( | ||
| 39 | + type, | ||
| 40 | + connection.user, | ||
| 41 | + message, | ||
| 42 | + callback | ||
| 43 | + ) | ||
| 44 | + ) | ||
| 45 | + return; | ||
| 46 | + | ||
| 47 | + if ( | ||
| 48 | + connection?.user && | ||
| 49 | + connection.user.handler.handle(type, connection.user, message, callback) | ||
| 50 | + ) | ||
| 51 | + return; | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + private handleLogin( | ||
| 55 | + connection: Connection, | ||
| 56 | + message: ServerInboundMessage<"login">, | ||
| 57 | + callback: Function | ||
| 58 | + ) { | ||
| 59 | + connection.user = new User(message.username, connection); | ||
| 60 | + console.log(`User ${message.username} has logged in!`); | ||
| 61 | + | ||
| 62 | + callback({ ok: true }); | ||
| 54 | } | 63 | } |
| 55 | } | 64 | } | ... | ... |
| 1 | import ioclient, { Socket } from "socket.io-client"; | 1 | import ioclient, { Socket } from "socket.io-client"; |
| 2 | -import { | ||
| 3 | - LoginMessage, | ||
| 4 | - MessageResponse, | ||
| 5 | - MessageType, | ||
| 6 | - RoomChatMessage, | ||
| 7 | - RoomJoinMessage, | ||
| 8 | - RoomLeaveMessage, | ||
| 9 | - RoomListRequestMessage, | ||
| 10 | - RoomUserUpdateMessage, | ||
| 11 | -} from "./message/types"; | ||
| 12 | import { expect } from "chai"; | 2 | import { expect } from "chai"; |
| 13 | import { Server } from "./Server"; | 3 | import { Server } from "./Server"; |
| 14 | -import { RoomDescription, RoomInfo } from "./room/types"; | ||
| 15 | import { response } from "express"; | 4 | import { response } from "express"; |
| 5 | +import { | ||
| 6 | + RawMessage, | ||
| 7 | + ServerInboundMessage, | ||
| 8 | + ServerInboundMessageKey, | ||
| 9 | + ServerOutboundMessage, | ||
| 10 | + ServerOutboundMessageKey, | ||
| 11 | + ServerResponse, | ||
| 12 | +} from "../common"; | ||
| 16 | 13 | ||
| 17 | describe("server", () => { | 14 | describe("server", () => { |
| 18 | const PORT = 3000; | 15 | const PORT = 3000; |
| ... | @@ -39,39 +36,58 @@ describe("server", () => { | ... | @@ -39,39 +36,58 @@ describe("server", () => { |
| 39 | client2.close(); | 36 | client2.close(); |
| 40 | }); | 37 | }); |
| 41 | 38 | ||
| 42 | - var roomUserUpdateMessage: RoomUserUpdateMessage; | 39 | + var roomUserUpdateMessage: ServerOutboundMessage<"updateRoomUser">; |
| 43 | - var roomChatMessage: RoomChatMessage; | 40 | + var roomChatMessage: ServerOutboundMessage<"chat">; |
| 41 | + | ||
| 42 | + const send = <T extends ServerInboundMessageKey>( | ||
| 43 | + socket: Socket, | ||
| 44 | + type: T, | ||
| 45 | + message: ServerInboundMessage<T>, | ||
| 46 | + callback: (response: ServerResponse<T>) => void | ||
| 47 | + ) => { | ||
| 48 | + socket.emit( | ||
| 49 | + "msg", | ||
| 50 | + { | ||
| 51 | + type: type as string, | ||
| 52 | + message: message, | ||
| 53 | + }, | ||
| 54 | + callback | ||
| 55 | + ); | ||
| 56 | + }; | ||
| 44 | 57 | ||
| 45 | step("register listeners", () => { | 58 | step("register listeners", () => { |
| 46 | - client1.on( | 59 | + client1.on("msg", (raw: RawMessage) => { |
| 47 | - MessageType.ROOM_USER_UPDATE, | 60 | + if (raw.type == "updateRoomUser") roomUserUpdateMessage = raw.message; |
| 48 | - (message: RoomUserUpdateMessage) => { | 61 | + }); |
| 49 | - roomUserUpdateMessage = message; | ||
| 50 | - } | ||
| 51 | - ); | ||
| 52 | 62 | ||
| 53 | - client1.on(MessageType.ROOM_CHAT, (message: RoomChatMessage) => { | 63 | + client1.on("msg", (raw: RawMessage) => { |
| 54 | - roomChatMessage = message; | 64 | + if (raw.type == "chat") roomChatMessage = raw.message; |
| 55 | }); | 65 | }); |
| 56 | }); | 66 | }); |
| 57 | 67 | ||
| 58 | step("login 1", (done) => { | 68 | step("login 1", (done) => { |
| 59 | - client1.emit( | 69 | + send( |
| 60 | - MessageType.LOGIN, | 70 | + client1, |
| 61 | - new LoginMessage("guest1"), | 71 | + "login", |
| 62 | - (response: MessageResponse<undefined>) => { | 72 | + { |
| 63 | - expect(response.ok).to.equals(true); | 73 | + username: "guest1", |
| 74 | + }, | ||
| 75 | + (response) => { | ||
| 76 | + expect(response.ok).to.eq(true); | ||
| 64 | done(); | 77 | done(); |
| 65 | } | 78 | } |
| 66 | ); | 79 | ); |
| 67 | }); | 80 | }); |
| 68 | 81 | ||
| 69 | step("login 2", (done) => { | 82 | step("login 2", (done) => { |
| 70 | - client2.emit( | 83 | + send( |
| 71 | - MessageType.LOGIN, | 84 | + client2, |
| 72 | - new LoginMessage("guest2"), | 85 | + "login", |
| 73 | - (response: MessageResponse<undefined>) => { | 86 | + { |
| 74 | - expect(response.ok).to.equals(true); | 87 | + username: "guest2", |
| 88 | + }, | ||
| 89 | + (response) => { | ||
| 90 | + expect(response.ok).to.eq(true); | ||
| 75 | done(); | 91 | done(); |
| 76 | } | 92 | } |
| 77 | ); | 93 | ); |
| ... | @@ -80,52 +96,40 @@ describe("server", () => { | ... | @@ -80,52 +96,40 @@ describe("server", () => { |
| 80 | var roomToJoin: string; | 96 | var roomToJoin: string; |
| 81 | 97 | ||
| 82 | step("room list", (done) => { | 98 | step("room list", (done) => { |
| 83 | - client1.emit( | 99 | + send(client1, "roomList", {}, (response) => { |
| 84 | - MessageType.ROOM_LIST_REQUEST, | 100 | + expect(response.ok).to.eq(true); |
| 85 | - new RoomListRequestMessage(), | 101 | + expect(response.result !== undefined).to.eq(true); |
| 86 | - (response: MessageResponse<RoomDescription[]>) => { | 102 | + if (response.result) { |
| 87 | - expect(response.ok).to.eq(true); | 103 | + expect(response.result[0].name).to.eq("테스트 방 #1"); |
| 88 | - expect(response.result !== undefined).to.eq(true); | 104 | + roomToJoin = response.result[0].uuid; |
| 89 | - if (response.result) { | ||
| 90 | - expect(response.result[0].name).to.eq("테스트 방 #1"); | ||
| 91 | - roomToJoin = response.result[0].uuid; | ||
| 92 | - } | ||
| 93 | - done(); | ||
| 94 | } | 105 | } |
| 95 | - ); | 106 | + done(); |
| 107 | + }); | ||
| 96 | }); | 108 | }); |
| 97 | 109 | ||
| 98 | step("room join 1", (done) => { | 110 | step("room join 1", (done) => { |
| 99 | - client1.emit( | 111 | + send(client1, "joinRoom", { uuid: roomToJoin }, (response) => { |
| 100 | - MessageType.ROOM_JOIN, | 112 | + expect(response.ok).to.eq(true); |
| 101 | - new RoomJoinMessage(roomToJoin), | 113 | + expect(response.result !== undefined).to.eq(true); |
| 102 | - (response: MessageResponse<RoomInfo>) => { | 114 | + if (response.result) { |
| 103 | - expect(response.ok).to.eq(true); | 115 | + expect(response.result.uuid).to.eq(roomToJoin); |
| 104 | - expect(response.result !== undefined).to.eq(true); | 116 | + expect(response.result.users.length).to.eq(1); |
| 105 | - if (response.result) { | 117 | + expect(response.result.users[0].username).to.eq("guest1"); |
| 106 | - expect(response.result.uuid).to.eq(roomToJoin); | ||
| 107 | - expect(response.result.users.length).to.eq(1); | ||
| 108 | - expect(response.result.users[0].username).to.eq("guest1"); | ||
| 109 | - } | ||
| 110 | - done(); | ||
| 111 | } | 118 | } |
| 112 | - ); | 119 | + done(); |
| 120 | + }); | ||
| 113 | }); | 121 | }); |
| 114 | 122 | ||
| 115 | step("room join 2", (done) => { | 123 | step("room join 2", (done) => { |
| 116 | - client2.emit( | 124 | + send(client2, "joinRoom", { uuid: roomToJoin }, (response) => { |
| 117 | - MessageType.ROOM_JOIN, | 125 | + expect(response.ok).to.eq(true); |
| 118 | - new RoomJoinMessage(roomToJoin), | 126 | + expect(response.result !== undefined).to.eq(true); |
| 119 | - (response: MessageResponse<RoomInfo>) => { | 127 | + if (response.result) { |
| 120 | - expect(response.ok).to.eq(true); | 128 | + expect(response.result.uuid).to.eq(roomToJoin); |
| 121 | - expect(response.result !== undefined).to.eq(true); | 129 | + expect(response.result.users.length).to.eq(2); |
| 122 | - if (response.result) { | ||
| 123 | - expect(response.result.uuid).to.eq(roomToJoin); | ||
| 124 | - expect(response.result.users.length).to.eq(2); | ||
| 125 | - } | ||
| 126 | - done(); | ||
| 127 | } | 130 | } |
| 128 | - ); | 131 | + done(); |
| 132 | + }); | ||
| 129 | }); | 133 | }); |
| 130 | 134 | ||
| 131 | // TODO: RoomUserUpdateMessage가 아직 도착하지 않았는데 실행되는 경우 | 135 | // TODO: RoomUserUpdateMessage가 아직 도착하지 않았는데 실행되는 경우 |
| ... | @@ -133,19 +137,15 @@ describe("server", () => { | ... | @@ -133,19 +137,15 @@ describe("server", () => { |
| 133 | expect(roomUserUpdateMessage !== undefined).to.eq(true); | 137 | expect(roomUserUpdateMessage !== undefined).to.eq(true); |
| 134 | if (roomUserUpdateMessage) { | 138 | if (roomUserUpdateMessage) { |
| 135 | expect(roomUserUpdateMessage.state).to.eq("added"); | 139 | expect(roomUserUpdateMessage.state).to.eq("added"); |
| 136 | - expect(roomUserUpdateMessage.userdata.username).to.eq("guest2"); | 140 | + expect(roomUserUpdateMessage.user.username).to.eq("guest2"); |
| 137 | } | 141 | } |
| 138 | }); | 142 | }); |
| 139 | 143 | ||
| 140 | step("client 2 send chat", (done) => { | 144 | step("client 2 send chat", (done) => { |
| 141 | - client2.emit( | 145 | + send(client2, "chat", { message: "Hello World" }, (response) => { |
| 142 | - MessageType.ROOM_CHAT, | 146 | + expect(response.ok).to.eq(true); |
| 143 | - new RoomChatMessage("Hello World"), | 147 | + done(); |
| 144 | - (response: MessageResponse<undefined>) => { | 148 | + }); |
| 145 | - expect(response.ok).to.eq(true); | ||
| 146 | - done(); | ||
| 147 | - } | ||
| 148 | - ); | ||
| 149 | }); | 149 | }); |
| 150 | 150 | ||
| 151 | step("client 1 received chat", () => { | 151 | step("client 1 received chat", () => { |
| ... | @@ -157,21 +157,17 @@ describe("server", () => { | ... | @@ -157,21 +157,17 @@ describe("server", () => { |
| 157 | }); | 157 | }); |
| 158 | 158 | ||
| 159 | step("client 2 leave", (done) => { | 159 | step("client 2 leave", (done) => { |
| 160 | - client2.emit( | 160 | + send(client2, "leaveRoom", {}, (response) => { |
| 161 | - MessageType.ROOM_LEAVE, | 161 | + expect(response.ok).to.eq(true); |
| 162 | - new RoomLeaveMessage(), | 162 | + done(); |
| 163 | - (response: MessageResponse<undefined>) => { | 163 | + }); |
| 164 | - expect(response.ok).to.eq(true); | ||
| 165 | - done(); | ||
| 166 | - } | ||
| 167 | - ); | ||
| 168 | }); | 164 | }); |
| 169 | 165 | ||
| 170 | step("client 1 received user update", () => { | 166 | step("client 1 received user update", () => { |
| 171 | expect(roomUserUpdateMessage !== undefined).to.eq(true); | 167 | expect(roomUserUpdateMessage !== undefined).to.eq(true); |
| 172 | if (roomUserUpdateMessage) { | 168 | if (roomUserUpdateMessage) { |
| 173 | expect(roomUserUpdateMessage.state).to.eq("removed"); | 169 | expect(roomUserUpdateMessage.state).to.eq("removed"); |
| 174 | - expect(roomUserUpdateMessage.userdata.username).to.eq("guest2"); | 170 | + expect(roomUserUpdateMessage.user.username).to.eq("guest2"); |
| 175 | } | 171 | } |
| 176 | }); | 172 | }); |
| 177 | }); | 173 | }); | ... | ... |
-
Please register or login to post a comment