개발자공부일기
패킷에 헤더 붙여서 전송하기 본문
export const spawnMonsterReqHandler = ({socket}) => {
const {user,opponent}=findUserGameOpponentBySocket(socket);
testLog(0,`spawnMonsterReqHandler에 user가 있을까? ${user}`,'blue');
testLog(0,`spawnMonsterReqHandler에 user.socket이 있을까? ${user.socket}`,'red');
const monster = spawnMonster(monsterid,monsterNum,user);
addMonster(monster);
const response = createS2CSpawnMonsterResponse(monster.monsterId,monster.monsterNumber,user);
const notification = createS2CSpawnEnemyMonsterNotification(monster.monsterId,monster.monsterNumber);
testLog(0,`response: ${response.toString('hex')}, notification: ${notification}`,'red');
user.socket.write(response);
opponent.socket.write(notification);
};
서버에서 몬스터스폰 req가 들어오면 response를 만들어서 다시 보내줄거다.
export const createS2CSpawnMonsterResponse = (monsterId,monsterNumber,user) => {
const protoMessages = getProtoMessages();
const dataType = protoMessages.test.GamePacket;
if(!dataType) {
throw new Error('dataType 메세지 정의 x');
}
testLog(0,`dataType: ${dataType}`,'green');
const payload = {
spawnMonsterResponse: {
monsterId,
monsterNumber,
}
};
testLog(0,`payload:${JSON.stringify(payload)} `,'yellow');
const message = dataType.create(payload);
const monsterSpawnPacket = dataType.encode(message).finish();
testLog(0,`message: ${JSON.stringify(message)}`,'red');
testLog(0,`monsterSpawnPacket: ${monsterSpawnPacket.toString('hex')}`,'blue');
// return makeNotification(monsterSpawnPacket,PACKET_TYPE.SPAWN_MONSTER_RESPONSE);
return payloadParser(PACKET_TYPE.SPAWN_MONSTER_RESPONSE,user,monsterSpawnPacket);
};
이게 payload를 만들어서 encode해서 보낼코드다
payloadParser 에서 만들어서 보내줄건데 상세 코드는 이렇다.
export const payloadParser = (packetType, user, Payload) => {
// 버전 문자열 준비
const version = config.client.version;
const versionBuffer = Buffer.from(version, 'utf8');
// 1. 패킷 타입 정보를 포함한 버퍼 생성 (2바이트)
const packetTypeBuffer = Buffer.alloc(config.packet.packetTypeLength);
packetTypeBuffer.writeUint16BE(packetType, 0);
// 2. 버전 길이 (1바이트)
const versionLengthBuffer = Buffer.alloc(config.packet.versionLengthLength);
versionLengthBuffer.writeUInt8(versionBuffer.length, 0);
// 3. 시퀀스 (4바이트, big endian)
const sequenceBuffer = Buffer.alloc(config.packet.sequenceLength);
sequenceBuffer.writeInt32BE(user.sequence);
// 4. 페이로드 길이 (4바이트, big endian)
const payloadLengthBuffer = Buffer.alloc(config.packet.payloadLengthLength);
payloadLengthBuffer.writeInt32BE(Payload.length);
// 5. 최종 패킷 데이터 생성
return Buffer.concat([
packetTypeBuffer,
versionLengthBuffer,
versionBuffer,
sequenceBuffer,
payloadLengthBuffer,
Payload,
]);
};
payload에 packetTypeBuffer versionLengthBuffer versionBuffer sequenceBuffer payloadLengthBuffer 헤더를 붙인다.
패킷 길이맞추고 packetnames에 이름 등록하고 패킷관련해서 정확히 맞추는게 굉장히 어려웠다.
'TIL(Today I Learned)' 카테고리의 다른 글
프로세스와 스레드, 컨텍스트 스위칭 (0) | 2025.01.27 |
---|---|
프로그래머스 문제:타켓 넘버 (0) | 2025.01.23 |
oneof (0) | 2025.01.22 |
게임 서버 아키텍처 (0) | 2025.01.20 |
운영체제 (0) | 2025.01.15 |