rabbit97 님의 블로그
21일 일지 본문
# 오늘 진행 사항
- 남은 마지막 핸들러까지 기능 토대 구현
- 위치 이동 업데이트 핸들러 로직 기능 병합
둘이 잘 만난다
import { getGameSessionBySocket } from '../../sessions/game.session.js';
import { createResponse } from '../../utils/packet/response/createResponse.js';
import config from '../../config/config.js';
import { getUserBySocket } from '../../sessions/user.session.js';
import handleError from '../../utils/errors/errorHandler.js';
const packetType = config.packet.packetType;
const handlePositionUpdate = async ({ socket, payload }) => {
try {
if (!payload || typeof payload !== 'object') {
throw new Error('Payload가 올바르지 않습니다.');
}
const { x, y } = payload;
if (typeof x === 'undefined' || typeof y === 'undefined') {
throw new Error('페이로드에 x 또는 y 값이 없습니다.');
}
const gameSession = getGameSessionBySocket(socket);
if (!gameSession) {
throw new Error('해당 유저의 게임 세션이 존재하지 않습니다.');
}
const currentUser = getUserBySocket(socket);
if (!currentUser) {
throw new Error('유저가 존재하지 않습니다.');
}
currentUser.setPos(x, y);
const positionResponseData = {
success: true,
failCode: 0,
};
console.log('Position Update Response Data:', positionResponseData);
const positionResponse = createResponse(
packetType.POSITION_UPDATE_RESPONSE,
socket.sequence,
positionResponseData,
);
socket.write(positionResponse);
/// 포지션 응답 완
const characterPositions = [];
const allUser = gameSession.getAllUsers();
allUser.forEach((user, i) => {
const posData = {
id: user.id,
x: user.x,
y: user.y,
};
characterPositions.push(posData);
});
console.log('Notification Response Data:', { characterPositions });
const notiData = {
characterPositions: characterPositions,
};
// 노티피케이션 생성 및 전송
const notificationResponse = createResponse(
packetType.POSITION_UPDATE_NOTIFICATION,
socket.sequence,
notiData,
);
allUser.forEach((notiUser) => {
notiUser.socket.write(notificationResponse);
});
} catch (error) {
handleError(socket, error);
}
};
export default handlePositionUpdate;
기능을 합치면서 생겼던 문제가 있었는데
서버 로그로도 위치 값이 패킷 명세에 맞게 잘 보내고 있고 유니티 쪽에서도 노티피케이션 패킷을 받았다고 로그가 나왔으나
움직임이 인식이 안되는 문제가 있었다.
문제는 이 부분
패킷 명세가 주어지고나서 패킷 명세가 바뀌었다고 공지가 한번 올라왔었는데
위치 이동 리스폰스가 원래 없었는데 추가가 되었다
당연히 24번에 리스폰스를 넣고 번호를 하나씩 미뤘는데
그냥 패킷 명세만 존재하고 클라이언트 부분에서는 번호 수정이 이루어지지 않아서 (확인해보니 위치 이동 리스폰스는 클라이언트에서 구현이 되어있지도 않았다 - 필요 없었던 로직)
리스폰스로 보내고 있던 24번을 클라이언트에서는 노티피케이션으로 알고 있었고
노티피케이션으로는
패킷 : message S2CPositionUpdateNotification { repeated CharacterPositionData characterPositions = 1; }
로그 : characterPositions: [
{ id: 4, x: -13.642138481140137, y: -5.00637149810791 },
{ id: 3, x: -15.202, y: -4.736 }
]
이 정보가 필요한데
서버에서 보낸 정보가
패킷 : message S2CPositionUpdateResponse { bool success = 1; GlobalFailCode failCode = 2; }
로그 : Position Update Response Data: { success: true, failCode: 0 }
이거여서 받았다고만 나오고 움직임은 보이지 않았던 것
로그로도 못찾았던 이유는
Position Update Response Data: { success: true, failCode: 0 }
Notification Response Data: {
characterPositions: [
{ id: 4, x: -13.642138481140137, y: -5.00637149810791 },
{ id: 3, x: -15.202, y: -4.736 }
]
}
이런 식으로 로그가 나오는데 당연히 24번이랑 25번을 잘 보내고 받고 있는 줄 알았다.
const positionResponse = createResponse(
packetType.POSITION_UPDATE_RESPONSE,
socket.sequence,
positionResponseData,
);
socket.write(positionResponse);
지금까지 24번으로 알고있었던 포지션 리스폰스를 계속 보내서 클라이언트에선 24번을 받았다고만 알림이 나오고
리스폰스는 보내기만 하고 아무런 기능을 하지 않는다.
이걸 발견한 방법은
팀원 중 카드쪽을 맡고 있던 분들이 자기쪽도 패킷이 주고 받는게 이상하다면서 원인을 찾다가
원인을 찾았는데 패킷 명세가 잘못 되어있는걸 발견하고
24번 뒤로 모두 하나씩 밀려있어서 내 로직도 말을 안듣고 있었던 것
금방 찾을 수 있었는데 아쉬웠던 점은 유니티에서 카드 관련해가지고 리퀘스트 요청을 계속 보냈었는데 그냥 카드쪽이 구현 안되어서 그런가보다 하고 그냥 넘겼었지만 지금보니 25번이 카드 사용 요청 로직이였다.
수정하고는 잘 작동한다.
그리고 추가한 애니메이션 핸들러
import { getGameSessionBySocket } from '../../sessions/game.session.js';
import { createResponse } from '../../utils/packet/response/createResponse.js';
import config from '../../config/config.js';
import { getUserBySocket } from '../../sessions/user.session.js';
import handleError from '../../utils/errors/errorHandler.js';
const packetType = config.packet.packetType;
const handleAnimationNotification = async ({ socket, payload }) => {
try {
if (!payload || typeof payload !== 'object') {
throw new Error('Payload가 올바르지 않습니다.');
}
const { userId, animationType } = payload;
if (typeof userId === 'undefined' || typeof animationType === 'undefined') {
throw new Error('페이로드에 userId 또는 animationType 값이 없습니다.');
}
const gameSession = getGameSessionBySocket(socket);
if (!gameSession) {
throw new Error('해당 유저의 게임 세션이 존재하지 않습니다.');
}
const currentUser = getUserBySocket(socket);
if (!currentUser) {
throw new Error('유저가 존재하지 않습니다.');
}
const animationResponseData = {
userId,
animationType,
};
console.log('Animation Notification Response Data:', animationResponseData);
const animationResponse = createResponse(
packetType.ANIMATION_NOTIFICATION,
socket.sequence,
animationResponseData,
);
// 현재 게임 세션의 모든 사용자에게 애니메이션 노티피케이션 전송
const allUser = gameSession.getAllUsers();
allUser.forEach((notiUser) => {
notiUser.socket.write(animationResponse);
});
} catch (error) {
handleError(socket, error);
}
};
export default handleAnimationNotification;
남은건 이제 작성 했던 로직들 합쳐서도 잘 작동할 수 있게 수정하는 것만 남았는데
생각보다 금방 할 수 있을 것 같아서 마음은 놓인다.