2 분 소요

이번 주 습득한 것

이번 주는 서버 작업을 할 때 필요한 개념들을 다시 정리하고 그걸 작동시키는 시간이 되었다. 이번 주에 배운 것들을 먼저 정리하고 그 후에 작업한 내용을 정리해보자.

커넥션 풀

데이터베이스와의 연결을 미리 여러 개 생성하여 풀에 저장하는 방식.
데이터베이스를 연결하여 객체를 생성하는 과정은 생각보다 많은 용량을 차지한다. 그래서 가능하면 미리 생성해놓고 그 생성된 데이터베이스 연결을 돌려 가는 방식을 뜻한다.

const pools = {
  GAME_DB: createPool(databases.GAME_DB),
  USER_DB: createPool(databases.USER_DB),
};

사용자가 많아질수록, 시스템이 복잡해질 수록 연결이 더 많이 필요해진다.

레이턴시

간단하게 서버와 클라이언트 등을 오가면서 생기는 딜레이라 보면 되며, 유저마다 동일한 경험을 제공해야 하기 때문에 중요하게 관리해야 하는 것이다.
딜레이에 따라 플레이어들의 이동 등을 처리해주는 방법으로는 추측항법이 있다.

calculatePosition(latency) {
    const timeDiff = latency / 1000; // 레이턴시를 초 단위로 계산
    const speed = 1; // 속도 고정
    const distance = speed * timeDiff;

    // x, y 축에서 이동한 거리 계산
    return {
      x: this.x + distance,
      y: this.y,
    };
  }

프로토콜 버퍼

기존에는 데이터를 받아오는 과정에서 데이터를 json 등의 범용적인 데이터를 사용해왔다. 해당 방법이 나쁘다는 건 아니지만 용량 문제에서 자유로울 수 없다는 사실은 존재한다.
좀 더 적은 용량, 메모리를 사용하면서 데이터를 전송할 방법을 사용해야 했고, 그것으로 고안된 것이 프로토콜 버퍼이다.

syntax = "proto3";

package common;

message Packet {
    uint32 handlerId = 1;
    string userId = 2;
    string clientVersion = 3;
    uint32 sequence = 4;
    bytes payload = 5;
}

message Ping {
    int64 timestamp = 1;
}

위와 같이 데이터를 받을 때 어떤 식으로 받을지를 미리 정해놓고, 그걸 통해 받은 버퍼를 나눠서 데이터를 받는 방식.
위의 데이터를 번역하자면 common이라는 package 안에 있는 packet이라는 메시지를 통해 읽는다면 {handlerId, userId, clientVersion, sequence, payload}의 순서로 읽겠다는 의미이다.

순서에 맞춰서 인코딩을 하고 디코딩을 하면 된다.

import protobuf from 'protobufjs';

//시퀀스 값을 이게 몇 번째 데이터인가를 저장하는 것. 
//시퀀스 값이 순차적이지 않을 경우 등을 검수할 수 있다.

protobuf.load("person.proto").then(root => {
  // 'person.proto' 파일을 로드합니다.

  const Person = root.lookupType("Person");
  // 'Person' 메시지 타입을 'root' 객체에서 찾습니다. 이는 person.proto 파일에서 정의한 메시지 타입입니다.

  const message = Person.create({ name: "John Doe", id: 123, email: "johndoe@example.com" });
  // 'Person' 메시지 타입을 사용하여 새로운 메시지 객체를 생성합니다. 여기서는 name, id, email 필드를 설정합니다.

  const buffer = Person.encode(message).finish();
  // 생성된 메시지 객체를 바이너리 형식으로 인코딩합니다. 'finish' 메서드는 최종 인코딩된 버퍼를 반환합니다.

  const decodedMessage = Person.decode(buffer);
  // 인코딩된 버퍼를 다시 메시지 객체로 디코딩합니다.

  console.log("Original message:", message);
  // 원래 생성된 메시지 객체를 콘솔에 출력합니다.

  console.log("Encoded buffer:", buffer);
  // 인코딩된 바이너리 버퍼를 콘솔에 출력합니다.

  console.log("Decoded message:", decodedMessage);
  // 디코딩된 메시지 객체를 콘솔에 출력합니다.

})

장점

  1. 대용량 데이터를 처리할 때 기존의 json 등보다 효율적이다.

    단점

  2. 가독성이 떨어진다.