강동현

방에서 User 객체를 사용하도록 변경

......@@ -8,7 +8,6 @@ export class Connection {
public readonly socket: Socket;
public user?: User;
public room?: Room;
constructor(socket: Socket) {
this.socket = socket;
......
import { Connection } from "../connection/Connection";
import { User } from "../user/User";
import { loginHandler } from "./handler/loginHandler";
import { roomJoinHandler } from "./handler/roomJoinHandler";
import { roomLeaveHandler } from "./handler/roomLeaveHandler";
......@@ -7,8 +8,16 @@ import { Message, MessageType } from "./types";
export class MessageHandlerRegistry {
static registerHandlers(connection: Connection) {
this.registerHandler(connection, MessageType.LOGIN, loginHandler);
this.registerHandler(connection, MessageType.ROOM_JOIN, roomJoinHandler);
this.registerHandler(connection, MessageType.ROOM_LEAVE, roomLeaveHandler);
this.registerHandlerAuthed(
connection,
MessageType.ROOM_JOIN,
roomJoinHandler
);
this.registerHandlerAuthed(
connection,
MessageType.ROOM_LEAVE,
roomLeaveHandler
);
}
private static registerHandler<T extends Message>(
......@@ -20,4 +29,16 @@ export class MessageHandlerRegistry {
handler(connection, message);
});
}
private static registerHandlerAuthed<T extends Message>(
connection: Connection,
typeName: string,
handler: (user: User, message: T) => void
) {
connection.socket.on(typeName, (message: T) => {
if (connection.user !== undefined) {
handler(connection.user, message);
}
});
}
}
......
......@@ -7,7 +7,7 @@ export function loginHandler(
connection: Connection,
message: LoginMessage
): void {
connection.user = new User(message.username);
connection.user = new User(message.username, connection);
console.log(`User ${message.username} has logged in!`);
RoomManager.instance().sendList(connection);
......
import { Connection } from "../../connection/Connection";
import { RoomManager } from "../../room/RoomManager";
import { User } from "../../user/User";
import { RoomJoinMessage } from "../types";
export function roomJoinHandler(
connection: Connection,
message: RoomJoinMessage
): void {
export function roomJoinHandler(user: User, message: RoomJoinMessage): void {
const room = RoomManager.instance().get(message.uuid);
if (room !== undefined) {
room.connect(connection);
room.connect(user);
}
}
......
import { Connection } from "../../connection/Connection";
import { RoomManager } from "../../room/RoomManager";
import { User } from "../../user/User";
import { RoomLeaveMessage } from "../types";
export function roomLeaveHandler(
connection: Connection,
message: RoomLeaveMessage
): void {
if (connection.room !== undefined) {
connection.room.disconnect(connection);
}
export function roomLeaveHandler(user: User, message: RoomLeaveMessage): void {
user.room?.disconnect(user);
}
......
......@@ -7,60 +7,50 @@ import {
RoomUserUpdateMessage,
} from "../message/types";
import { UserData } from "../user/types";
import { User } from "../user/User";
export class Room {
public readonly uuid: string;
public name: string;
public readonly maxConnections: number;
public readonly maxUsers: number;
private connections: Connection[] = [];
private users: User[] = [];
private closed: boolean = false;
constructor(name: string, maxConnections: number = 8) {
constructor(name: string, maxUsers: number = 8) {
this.uuid = uuidv4();
this.name = name;
this.maxConnections = maxConnections;
this.maxUsers = maxUsers;
}
public connect(connection: Connection): void {
// TODO: 더 나은 인증 처리
const user = connection.user;
if (user === undefined) {
public connect(user: User): void {
if (this.users.includes(user) || this.users.length >= this.maxUsers) {
return;
}
if (
this.connections.includes(connection) ||
this.connections.length >= this.maxConnections
) {
return;
}
this.connections.push(connection);
connection.room = this; // TODO: 더 나은 관리
this.users.push(user);
user.room = this; // TODO: 더 나은 관리
this.broadcast(new RoomUserUpdateMessage("added", user.getData()));
var users: UserData[] = [];
this.connections.forEach((con) => {
if (con.user !== undefined && connection !== con) {
users.push(con.user.getData());
this.users.forEach((u) => {
if (user !== u) {
users.push(u.getData());
}
});
connection.send(new RoomInfoMessage(users));
user.connection.send(new RoomInfoMessage(users));
}
public disconnect(connection: Connection): void {
const index = this.connections.indexOf(connection);
if (connection.user !== undefined && index > -1) {
this.connections.splice(index, 1);
connection.room = undefined;
public disconnect(user: User): void {
const index = this.users.indexOf(user);
if (index > -1) {
this.users.splice(index, 1);
user.room = undefined;
this.broadcast(
new RoomUserUpdateMessage("removed", connection.user.getData())
);
this.broadcast(new RoomUserUpdateMessage("removed", user.getData()));
}
}
......@@ -68,22 +58,22 @@ export class Room {
return {
uuid: this.uuid,
name: this.name,
currentConnections: this.connections.length,
maxConnections: this.maxConnections,
currentUsers: this.users.length,
maxUsers: this.maxUsers,
};
}
public broadcast(message: Message, except?: Connection): void {
this.connections.forEach((connection) => {
if (connection !== except) {
connection.send(message);
public broadcast(message: Message, except?: User): void {
this.users.forEach((u) => {
if (u !== except) {
u.connection.send(message);
}
});
}
public close(): void {
if (!this.closed) {
this.connections.forEach((connection) => this.disconnect(connection));
this.users.forEach((u) => this.disconnect(u));
this.closed = true;
}
}
......
export interface RoomData {
uuid: string;
name: string;
currentConnections: number;
maxConnections: number;
currentUsers: number;
maxUsers: number;
}
......
import { Connection } from "../connection/Connection";
import { Room } from "../room/Room";
import { UserData } from "./types";
export class User {
public readonly username: string;
constructor(username: string) {
public readonly connection: Connection;
public room?: Room;
constructor(username: string, connection: Connection) {
this.username = username;
this.connection = connection;
}
public getData(): UserData {
......