Node 강의/심화

1-5 핸들러, 제약조건 적용하기

kagan-draca 2024. 10. 18. 17:14

1. 어떤 핸들러와 조건을 설정할 것인가?

 

핸들러

핸들러 ID 작업
10 소문자를대문자로 변경
11 데이터를 역순으로 변경

 

제한 조건

  • 메시지의 크기가 1024 바이트 보다 큰 경우에는 에러 반환 이후 커넥션 해제

 

2. 제한된 크기를 설정해줬기 때문에 Server에서 Client가 범위 내 메시지 보냈는지 확인하기

 

먼저, constant.js에서

export const MAX_MESSAGE_LENGTH = 1024;
// Clinet가 서버로 보낼 메시지 가능 최대 길이

위와 같이 메시지 제한 크기를 작성해줍니다.

 

수정된 이후 : 

export const TOTAL_LENGTH_SIZE = 4;
export const HANDLER_ID = 2;
export const MAX_MESSAGE_LENGTH = 1024;
// Clinet가 서버로 보낼 메시지 가능 최대 길이

 

그리고, server.js에서는 

  socket.on('data', (data) => {

으로 Client가 보내는 데이터를 수신 하는 부분이 존재하는데

이 골백 함수 내부에 현재 

    const { length, handlerId } = readHeader(buffer);

으로 해더에서 메시지의 길이 정보를 가져올 수 가져올 수 있습니다.

 

    if (length > MAX_MESSAGE_LENGTH) {
      console.error(`Error : Message Length ${length}`);
      socket.write(`Error : Message Too Long`);
      socket.end();
      return;
    }

 

그래서, if 문으로 length > MAX_MESSAGE_LENGTH로

Client가 보낸 Message가 제한된 길이 보다 클 경우

 

 서버에서 Error 발생했다고 출력하고, Error를 Client에게 전송해줍니다.

그리고, socket.end()로 Client와의 연결을 종료시킵니다.

 

client에서 일부러 오류가 날 메시지를 보내면

서버에서 Error를 출력하고 통신을 종료시키기 때문에,

 

Client에서는

Server가 보낸 메시지가 너무 길다는 답변과 연결이 종료되는 것을 확인할 수 있습니다.

 

3. handlerId에 따른 Event 처리 구간 만들기

1) handler10은 소문자를 대문자로 변경하는 함수 입니다.

 

handerId에 따른 Event가 다른 함수에서 처리하게 하기 위해

 

최상위 폴더에서 handlers 폴더를 만들고 handler10.js를 만들어

const handler10 = (data)=>{
    // data는 Buffer 객체가 들어올거라
    const processData = data.toString().toUpperCase();
    // string 타입으로 변경하고 대문자로 만들어준다.
    return Buffer.from(processData)
}

위와 같은 내용을 추가해줍니다.

 

handler10번은 

 

그리고, index.js에

import handler10 from './handler10.js';

const handlers = {
  10: handler10,
};

export default handlers;

 

const handlers 객체를 생성해 handler10번을 등록해줍니다.

 

등록한 handler에 따른 처리를 서버가 하기 위해 server.js에서 

socket.on('data', (data) => {

메서드에 handlerId 유무를 확인하는 코드를 작성해줍니다.

 

    const handler = handlers[handlerId];

    if (!handler) {
      console.error(`Error : No Handler Found For ID  ${handlerId}`);
      socket.write(`Error Invalid Handler ID ${handlerId}`);
      socket.end();
      return;
    }

 

!handlers[handlerId]로 

 

handlers객체에 handlerId가 존재하지 않으면

오류를 서버에 띄우고, 클라이언트에게 응답으로 보냅니다.

그리고, 통신을 종료합니다.

 

만약, Client가 없는 HandlerId로 Server에 message를 보내면,

왼쪽은 Server에서 출력되는 오류, 오른쪽은 Client가 Server에게서 수시한 메시지

Server에서는 Handler 11 번을 찾을 수 없다는 에러 메시지와,

Client는 Server가 응답한 오류 메시지 및 연결이 종료됩니다.

 

만약, 실제로 handler가 존재한다면, 해당 handler로 이밴트를 처리하기 위해

기존의 

    const responseBuffer = Buffer.from(responseMessage);
    // Buffer.from()로 보낼 메세지를 Buffer에 담아줍니다.

    const responseBuffer = handler(responseMessage);
    // Evnet에 따른 handler로 message를 처리합니다.
    // return 결과는 처리된 결과를 Buffer에 담은 배열입니다.

으로 수정해줍니다.

 

정상 동작을 확인하기 위해 Clinet가 Server로

  const message = 'Hello';

를 보내는 상황으로 하겠습니다.

원쪽은 Server에서 Client가 보낸 메시지를 수신한 결과, 오른쪽은 Client가 Server에게서 응답으로 받은 메시지

 

보는 결과와 같이, Client가 Server에게 "Hello"를 보낼 경우 서버는 "Hello"를 수신하고

Server는 수신한 결과 Hander Id가 10번인 함수로 Client의 message를 수신해 처리하여

"HELLO"가 출력되는 걸 확인할 수 있습니다.

 

2) handler11은 데이터를 역순으로 변경하는  Event 입니다.

handlers 폴더에 handler11.js를 만들어줍니다. 그리고,

const handler11 = (data) => {
  const processData = data.toString().split('').reverse().join('');
  // Buffer 형태로 온 배열을 문자열로 바꿔줍니다.
  // 배열로 만들어 배열을 뒤집어줍니다.
  // 뒤집은 배열을 문자열로 다시 바꿔줍니다.
  return Buffer.from(processData);
  // 처리된 결과를 다시 Buffer에 넣어 반환해줍니다.
};

export default handler11;

(캬~ 정답 안 보고 구현했는데 튜터님이랑 똑같은 코드!!! (뿌듯))

 

위와 같이 Buffer 형태로 온 배열을 문자열로 바꾸고 단어 하나하나를 나눠 배열 형태로 만든 후,

배열을 뒤집어 줍니다. 그 후, 뒤집은 배열을 join('')으로 문자열로 다시 만들어 준 후 

Buffer에 담아 배열 형태로 만들어줍니다.

 

결과를 출력해보면,

왼쪽은 Server가 Client에게 받은 메시지이고, 오른쪽은 Client가 Server에게 응답으로 받은 메시지 입니다.