CS와 Node.js 12. TCP, UDP, HTTP 파서 구현, JSON 기반 통신, TCP 서버 구현, TypeScript 설정

박재하·2023년 11월 3일
0

CS와 Node.js

목록 보기
12/12

TCP vs. UDP

TCP와 UDP의 특징 및 차이점 알아보기

  • TCP는 연결형, UDP는 비연결형 서비스임
  • TCP는 가상 회선 방식, UDP는 데이터그램 방식으로 패킷을 교환함
  • TCP는 전송 순서를 보장하지만, UDP는 바뀔 수 있음 (비동기)
  • TCP는 Handshake로 수신 여부를 확인하지만, UDP는 확인하지 않음
  • 위의 이유로 TCP는 신뢰성이 높은 반면 속도가 느리고, UDP는 속도가 빠른 반면 신뢰성이 낮은 게 주요 특징임
  • 또한 TCP는 주로 1:1 통신, UDP는 1:1/1:N/N:N 통신에 모두 활용될 수 있음

UDP로 서버 구현

  • 불가능한 것은 아니지만, 요청량도 많지 않고, 세션 연결을 기반으로 체크인 후에만 사용할 수 있는 기능을 처리한다던가 하는 부분이 많아서
  • 결론적으로 굳이 UDP를 사용할 필요는 없어보인다.
  • UDP는 주로 게임이나 파일 전송 같이 빠르고 비동기처리가 효율적인 서비스에서 많이 사용된다.
  • 다음은 node.js의 udp 모듈 dgram

Nodejs의 Tcp, Udp

HTTP 요청

HTTP 요청을 효율적으로 구현한 방식에 대해 설명하겠다.

https://user-images.githubusercontent.com/138586629/257697764-b5269d25-a572-498f-81ed-528ac22cddd3.png

위와 같이 HTTP에서 지원하는 Content-Type: application/json을 이용해 JSON임을 명시하고, 실질적인 데이터는 JSON.ParseJSON.Stringify로 파싱 및 전달해주면 된다.

%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2023-08-02_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_6 33 20

잘못된 요청의 경우 HTTP/1.1 400 Bad Request로 응답해줬다.

JSON 데이터 구조

일관된 데이터 처리를 위해 다음과 같이 구성해줬다.

Request JSON

{
  "cmd" : 커맨드(checkin, mission 등),
  "ops" : 파라미터 매열(campId, message 등),
}
  • 실질적인 처리는 서버에서 예외처리 하여 포맷에 맞는 경우에만 처리하도록 한다.
  • 커맨드마다 다른 구조로 만들어 새로운 key를 할당하면, 따로 확인을 해줘야 하기 때문에 생산성도 떨어지고 TypeScript 등으로 리팩토링 시 타입 정의가 까다로워진다.

Response JSON

{
  "cmd" : 커맨드(checkin, mission 등),
  "success" : 불리언(true/false),
  "message" : 콘솔 출력용 응답 메세지,
}
  • 응답 JSON도 같은 이유로 최대한 심플하고, 범용성 있게 구성했다.
  • success 여부를 true/false로 확인할 수 있게 하였고,
  • message는 string으로 서버에서 정리해서 보내서 추가적인 처리가 필요없게 했다. 이렇게 하면 클라이언트 및 서버 연동을 위해 머리를 싸맬 필요 없이 서버만 잘 구성해주면 된다.

Session을 이용한 재연결

  • HTTP Session은 아니지만, sessionId를 구분자로 부여해두었으며 해당하는 연결 정보는 모두 Camper() 인스턴스에 저장되어 있기 때문에 가능하다
  • TCP 재연결 시 remote(클라이언트) IP 정보를 이용하여, TCP 연결이 끊어질 때 체크아웃하는 기능을 빼고 다시 해당 인스턴스를 camper에다 부여하면 재연결을 구현할 수 있겠다.
// 처음 연결 시
const sessionInfo = [];
...
this.lastSessionId++;
const camper = new Camper(this.lastSessionId, socket);
sessionInfo.push({ // 처음 연결시 IP와 sessionId 매핑해놓고
	remoteAddress: socket.remoteAddress,
	sessionId: sessionId,
	userStatus: camper,
});
// 재연결 시 일치하는 IP가 있으면
const found = sessionInfo.filter((info) => info.remoteAddress === socket.remoteAddress);
if (found) {
	// userSatatus 재활용
	const camper = found.userStatus;
}

UDP를 쓴다면

  • 이미 위에서 다루었지만 다시 한번 언급하면 UDP는 비동기 처리가 필요하고 빠른 통신이 중요한 경우에 주로 사용된다.
  • 해설영상 스트리밍 서비스를 사용한다면 유용할 수도 있겠다.

하지만 아니였다.

QUIC (Quick UDP Internet Connection) 개념

  • 해설 영상을 보니 이것도 예전얘기고, 요즘엔 QUIC이라고 해서 TCP 대신 **UDP 기반의 프로토콜**을 널리 사용중이라고 한다.
  • 언젠가 더 파볼 기회가 있기를!

웹서버와 비교

  • 쿠키, 세션 등을 통한 관리가 소홀하며, 체크인/체크아웃 인증 과정이 부실함
  • HTTP 요청/응답 및 JSON을 이용해 요청을 처리하는 부분은 일반적인 JS 기반 서버와 비슷하다고 할 수 있음

참고 자료

문제 해결

TypeScript 설정 통일 방법

  • 다른사람이 작성한 TS 프로젝트가 정상적으로 실행되지 않는 문제. tsconfig의 설정 문제인 것으로 보임
    • 드디어 해결! 아래와 같이 tsconfig.json 설정하고 ts-node로 실행해주면 된다.
        {
          "compilerOptions": {
            /* Language and Environment */
            "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */

            /* Modules */
            "module": "commonjs",                                /* Specify what module code is generated. */
            "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
            "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */

            /* Type Checking */
            "strict": false,                                      /* Enable all strict type-checking options. */
            "skipLibCheck": true,                                 /* Skip type checking all .d.ts files. */
            "types": [
              "node"
            ]
          }
        }
  • 그리고 패키지도 3개 설치해주면 된다.
npm i -D typescript @types/node ts-node
# "@types/node": "^20.4.6",
# "ts-node": "^10.9.1",
# "typescript": "^5.1.6"
profile
해커 출신 개발자

0개의 댓글