강동현

RoomInfoMessage를 콜백 데이터로 전환

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