Project_xxx

[Project_] RTG - Trouble Shooting 2

wakelight23 2024. 12. 19. 22:26

Real Time Game - WebSocket 통신 방식을 이용한 게임 만들기 - 2

● 클라이언트에서 얻은 점수를 서버에서 검증하기까지 과정

  

왜 serverScore가 0이지...?

● Item을 먹으면 item.json에 등록된 효과 및 점수가 증가하거나 발동되도록 구현하던 중에 발생한 에러(?)

  - 설계상으로는 클라이언트에서는 올바르게 payload를 통해 정보를 서버에 주고 있었다.

// public/js/ItemController.js
sendEvent(21, payload, (response) => {
        if (response.status === 'success') {
          console.log('Item validated successfully:', response);
          score.updateScore(response.newScore); // 점수 업데이트
        } else {
          console.error('Failed to validate item:', response.message);
        }
      });

 - Item에 대한 처리를 하기 위해 handlerMappings에도 '21' 항목을 추가했고
   디버깅을 통해 payload가 잘 받는지도 확인했다.

 

// src/handlers/item.handler.js
// 서버 기준 점수 계산
const serverScore = getItem(userId)?.score || 0;
const expectedScore = serverScore + itemInfo.score; // 예상되는 점수

console.log('serverScore : ', serverScore);
console.log('expectedScore : ', expectedScore);

- 또한 item.json을 사용하기 위해 stage.model.js을 정의했던 것 같이 비슷하게 userId를 받아오는
  model 또한 구현했다.

// src/models/item.model.js
let userItems = {}; // 간단한 메모리 저장소

export const getItem = (uuid) => {
  return userItems[uuid] || null;
};

export const setItem = (uuid, score) => {
  if (!userItems[uuid]) {
    userItems[uuid] = { score };
  } else {
    userItems[uuid].score = score;
  }
};

- 프로젝트에서는 userId에 대한 정보를 uuid로 변형하여 받아오고 있기 때문에 uuid를 받아오도록 변수 설정

 

이렇게 점수를 받아오고 이제 디버깅으로 serverScore를 확인해보는데...

// vscode terminal에서 디버깅 했을 때 나왔던 값

userId: 'c1cb690f-32ff-4ce1-b57b-a46a2ce0e824',
  clientVersion: '1.0.0',
  handlerId: 21,
  payload: {
    itemId: 1,
    currentStageId: 1002,
    clientScore: 56.86139999999993,
    timestamp: 1734613046250
  }

serverScore : 0
expectedScore : 10

-  작성한 코드대로라면 serverScore가 clientScore와 같은 점수가 나왔어야 한다.

- 그럼에도 0이 나와서 이를 해결하기 위해 코드를 다시 읽고 디버깅도 해보았다.

 

디버깅 결과

● userId는 잘 받아오고 있었고 가장 큰 과정이 빠져있었다.

  → 클라이언트에서 받은 score를 서버에는 업데이트 되고 있지 않았다...

 

Score에 대한 데이터는 어디서 업데이트 되더라?

// public/js/Score.js
// 일정 점수가 될 때 스테이지가 변경되는 로직
  async update(deltaTime) {
    if (!this.userId) return; // userId가 없으면 업데이트 중단

    // 점수 증가
    this.score += deltaTime * 0.001;
    });
... // 생략
}

- public 디렉토리에 있는 Score.js에서 업데이트 하고 있다.
- 정작 서버에 점수를 보내서 통신하는 과정이 없던 것이었다...

 

// public/js/Score.js 
// 일정 점수가 될 때 스테이지가 변경되는 로직
  async update(deltaTime) {
    if (!this.userId) return; // userId가 없으면 업데이트 중단

    // 점수 증가
    this.score += deltaTime * 0.001;

    sendEvent(22, { userId: this.userId, clientScore: this.score }, (response) => {
      if (response.status === 'success') {
        this.score = response.newScore; // 서버에서 반환된 최신 점수로 동기화
      } else {
        console.error('Failed to update score on server:', response.message);
      }
    });
... // 생략
}

- handlerMapping을 하나 더 추가해서 증가하는 점수를 서버에서도 처리하는 handler 추가

 

status : Success!

// vscode terminal에서 출력되는 log
Handler response: {
  status: 'success',
  message: 'Score updated successfully',
  newScore: 46.826199999999936
}
Received data from client: {
  userId: 'c1cb690f-32ff-4ce1-b57b-a46a2ce0e824',
  clientVersion: '1.0.0',
  handlerId: 22,
  payload: {
    userId: '17a88659-e91d-4e72-b985-194927af81af',
    clientScore: 46.86139999999993
  }
}

- 클라이언트에서 점수를 보내고 서버에서도 받고 있는 것에 대한 Log이다.

 

● 모든 검증절차를 마치고 점수도 증가하고 있으면서 아이템을 먹었을 때 받는 Log ▼

Received data from client: {
  userId: 'c1cb690f-32ff-4ce1-b57b-a46a2ce0e824',
  clientVersion: '1.0.0',
  handlerId: 21,
  payload: {
    itemId: 1,
    currentStageId: 1002,
    clientScore: 56.86139999999993,
    timestamp: 1734613046250
  }
}
Received userId from client: c1cb690f-32ff-4ce1-b57b-a46a2ce0e824
validateItemHandler Payload: {
  itemId: 1,
  currentStageId: 1002,
  clientScore: 56.86139999999993,
  timestamp: 1734613046250
}
stageInfo :  { id: 1002, unlockedItems: [ 1, 2, 3 ] }
serverScore :  46.86139999999993
expectedScore :  56.86139999999993
Item validated successfully: {
  userId: 'c1cb690f-32ff-4ce1-b57b-a46a2ce0e824',
  itemId: 1,
  currentStageId: 1002
}

 

주거니... 받거니!

 

결론

● 결국은 Socket 통신 방식에 대한 원리를 제대로 이해하지 못해 일어났던 일이었다.

 

● Score를 처리하는 과정을 작성하면서 Socket 통신에 대해 한 발짝 더 이해가 된 느낌이다.