Skip to content

Commit

Permalink
chore: sse 데이터 구조 변경 (#188)
Browse files Browse the repository at this point in the history
  • Loading branch information
student079 authored Nov 28, 2024
1 parent fd520c8 commit def2350
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 101 deletions.
104 changes: 31 additions & 73 deletions be/gameServer/src/modules/rooms/rooms.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
NotFoundException,
Query,
Delete,
ParseIntPipe,
} from '@nestjs/common';
import { RedisService } from '../../redis/redis.service';
import { RoomDataDto } from './dto/room-data.dto';
Expand Down Expand Up @@ -52,93 +53,50 @@ export class RoomController {
description: '현재 페이지의 게임 방 목록이 성공적으로 반환됩니다.',
type: [RoomDataDto],
})
getRoomUpdates(@Query('page') page: number = 0): Observable<MessageEvent> {
getRoomUpdates(
@Query('page', ParseIntPipe) page: number = 0,
): Observable<MessageEvent> {
const start = page * RoomsConstant.ROOMS_LIMIT;
const end = start + RoomsConstant.ROOMS_LIMIT - 1;

return this.roomUpdateSubject.pipe(
concatMap(async (event: MessageEvent) => {
const messageString = event.data as string;
const message = JSON.parse(messageString);
const { type, key, nextPage, deletedPage } = message;
const updatedRoomKey = key ? key.slice(5) : null;
const totalRooms = await this.redisService.llen('roomsList');
const totalPages = Math.ceil(totalRooms / RoomsConstant.ROOMS_LIMIT);
const roomList = await this.redisService.lrange(
'roomsList',
start,
end,
);
if (type === 'CREATE') {
if (roomList.includes(updatedRoomKey)) {
const rooms = await Promise.all(
roomList.map(async (roomKey) => {
const roomData = await this.redisService.hgetAll<RoomDataDto>(
`room:${roomKey}`,
);
return roomData;
}),
);
return {
data: rooms,
} as MessageEvent;
} else {
return null;
}
} else if (type === 'DELETE') {
if (page != deletedPage) {
return null;
} else {
const rooms = await Promise.all(
roomList.map(async (roomKey) => {
const roomData = await this.redisService.hgetAll<RoomDataDto>(
`room:${roomKey}`,
);
return roomData;
}),
);

if (rooms.length === RoomsConstant.ROOMS_LIMIT) {
const nextPageEvent = {
data: JSON.stringify({
type: 'UPDATE',
nextPage: Number(page) + 1,
}),
};
const messageString = event.data as string;
const message = JSON.parse(messageString);
const { updatePage } = message;

this.roomUpdateSubject.next(nextPageEvent);
}
return {
data: rooms,
} as MessageEvent;
}
} else if (type === 'UPDATE') {
if (page != nextPage) {
return null;
}
const rooms = await Promise.all(
roomList.map(async (roomKey) => {
const roomData = await this.redisService.hgetAll<RoomDataDto>(
`room:${roomKey}`,
);
return roomData;
}),
);
if (updatePage !== undefined && updatePage != page) {
return null;
}

if (rooms.length === RoomsConstant.ROOMS_LIMIT) {
const nextPageEvent = {
data: JSON.stringify({
type: 'UPDATE',
nextPage: Number(page) + 1,
}),
};
this.logger.log(
`SSE 업데이트 이벤트 현재 page: ${Number(page)} 다음 page: ${Number(page) + 1}`,
const rooms = await Promise.all(
roomList.map(async (roomKey) => {
const roomData = await this.redisService.hgetAll<RoomDataDto>(
`room:${roomKey}`,
);
this.roomUpdateSubject.next(nextPageEvent);
}
return {
data: rooms,
} as MessageEvent;
}
return roomData;
}),
);
return {
data: {
rooms: rooms,
pagination: {
currentPage: Number(page),
totalPages,
totalItems: totalRooms,
hasNextPage: page < totalPages - 1,
hasPreviousPage: page > 0,
},
},
} as MessageEvent;
}),
filter((event: MessageEvent) => event !== null),
);
Expand Down
48 changes: 39 additions & 9 deletions be/gameServer/src/modules/rooms/rooms.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@ export class RoomsGateway implements OnGatewayDisconnect {
};

await this.redisService.rpush(RedisKeys.ROOMS_LIST, roomId);

await this.redisService.hmset<string>(
`room:${roomId}`,
convertRoomDataToHash(roomData),
RedisKeys.ROOMS_UPDATE_CHANNEL,
);

await this.redisService.rpush(
`${RedisKeys.ROOM_NAME_TO_ID_HASH}:${roomName}`,
roomId,
Expand Down Expand Up @@ -123,12 +125,22 @@ export class RoomsGateway implements OnGatewayDisconnect {
}

roomData.players.push({ playerNickname, isReady: false, isMuted: false });

const totalRoomIdList = await this.redisService.lrange(
`${RedisKeys.ROOMS_LIST}`,
0,
-1,
);
const index = totalRoomIdList.indexOf(roomId);
await this.redisService.hmset(
`room:${roomId}`,
{
players: JSON.stringify(roomData.players),
},
RedisKeys.ROOMS_UPDATE_CHANNEL,
...(index === -1
? []
: [Math.floor(index / RoomsConstant.ROOMS_LIMIT)]),
);

client.join(roomId);
Expand Down Expand Up @@ -162,6 +174,12 @@ export class RoomsGateway implements OnGatewayDisconnect {
// 이 상태에서 다른 사용자가 방에 들어온다면?

if (roomData.hostNickname === playerNickname) {
const totalRoomIdList = await this.redisService.lrange(
`${RedisKeys.ROOMS_LIST}`,
0,
-1,
);
const index = totalRoomIdList.indexOf(roomId);
if (roomData.players.length > 0) {
changeRoomHost(roomData);
await this.redisService.hmset(
Expand All @@ -171,6 +189,9 @@ export class RoomsGateway implements OnGatewayDisconnect {
hostNickname: roomData.hostNickname,
},
RedisKeys.ROOMS_UPDATE_CHANNEL,
...(index === -1
? []
: [Math.floor(index / RoomsConstant.ROOMS_LIMIT)]),
);

this.logger.log(`host ${playerNickname} leave room`);
Expand All @@ -192,28 +213,28 @@ export class RoomsGateway implements OnGatewayDisconnect {
if (roomNameList.length === 0) {
await this.redisService.zrem('roomNames', roomData.roomName);
}
const totalRoomIdList = await this.redisService.lrange(
`${RedisKeys.ROOMS_LIST}`,
0,
-1,
);
const index = totalRoomIdList.indexOf(roomId);
await this.redisService.lrem(RedisKeys.ROOMS_LIST, roomId);
await this.redisService.delete(
`room:${roomId}`,
RedisKeys.ROOMS_UPDATE_CHANNEL,
...(index === -1
? []
: [Math.floor(index / RoomsConstant.ROOMS_LIMIT)]),
);
}
} else {
const totalRoomIdList = await this.redisService.lrange(
`${RedisKeys.ROOMS_LIST}`,
0,
-1,
);
const index = totalRoomIdList.indexOf(roomId);
await this.redisService.hmset(
`room:${roomId}`,
{
players: JSON.stringify(roomData.players),
},
RedisKeys.ROOMS_UPDATE_CHANNEL,
...(index === -1
? []
: [Math.floor(index / RoomsConstant.ROOMS_LIMIT)]),
);
this.logger.log(`host ${playerNickname} leave room`);
this.server.to(roomId).emit('updateUsers', roomData.players);
Expand Down Expand Up @@ -334,12 +355,21 @@ export class RoomsGateway implements OnGatewayDisconnect {

if (targetSocket) {
roomData.players.splice(playerIndex, 1);
const totalRoomIdList = await this.redisService.lrange(
`${RedisKeys.ROOMS_LIST}`,
0,
-1,
);
const index = totalRoomIdList.indexOf(roomId);
await this.redisService.hmset(
`room:${roomId}`,
{
players: JSON.stringify(roomData.players),
},
RedisKeys.ROOMS_UPDATE_CHANNEL,
...(index === -1
? []
: [Math.floor(index / RoomsConstant.ROOMS_LIMIT)]),
);

this.server.to(roomId).emit('kicked', playerNickname);
Expand Down
25 changes: 6 additions & 19 deletions be/gameServer/src/redis/redis.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,17 @@ export class RedisService implements OnModuleDestroy {
key: string,
fields: Record<string, T>,
channel?: string,
ttlInSeconds?: number,
updatePage?: number,
): Promise<void> {
const fieldsArray = Object.entries(fields).flat();
await this.redisClient.hmset(key, ...fieldsArray);

if (ttlInSeconds) {
await this.redisClient.expire(key, ttlInSeconds);
}

if (channel) {
await this.publishToChannel(
channel,
JSON.stringify({ type: 'CREATE', key }),
JSON.stringify({
...(updatePage !== undefined ? { updatePage } : {}),
}),
);
}
}
Expand Down Expand Up @@ -115,21 +113,10 @@ export class RedisService implements OnModuleDestroy {
return value ? JSON.parse(value) : null;
}

async delete(
key: string,
channel?: string,
deletedPage?: number,
): Promise<void> {
async delete(key: string, channel?: string): Promise<void> {
await this.redisClient.del(key);
if (channel) {
await this.publishToChannel(
channel,
JSON.stringify({
type: 'DELETE',
key,
...(deletedPage !== undefined ? { deletedPage } : {}),
}),
);
await this.publishToChannel(channel, JSON.stringify({}));
}
}

Expand Down

0 comments on commit def2350

Please sign in to comment.