2024-04-11 (83일차) - 통신, 채팅

·2024년 4월 11일

폴링 통신 방식

  1. 브라우저가 서버에서 전화걸고 '뭔일있음?'
  2. 서버가 브라우저한테 'ㅇㅇ있음' 'ㄴㄴ없음' 하고 끊음
  3. 1번~2번 반복

... 개선한건 ...

sse 통신방식

  1. 브라우저가 서버한테 전화를 걸음
  2. 서버가 응답을 안하지만 안끊음.
  3. 뭔일 있을때만 응답함 (이벤트 발생시에만)


메세지를 그리는 구조(폴링)

poster

메세지를 작성하는 구조

poster


record란?

이 코드는 Java에서 Java 14부터 도입된 Record 타입을 사용하는 것으로 보입니다. Record는 데이터를 담는 간단한 클래스를 생성하는 데 사용됩니다. 이 경우 writeMessageRequest라는 레코드를 정의하고 있습니다.
writeMessageRequest 레코드는 두 개의 필드를 가지고 있습니다: authorName과 content. 이 레코드를 사용하면 이 두 필드를 가진 데이터 객체를 쉽게 만들 수 있습니다.

@Controller
@RequestMapping("/chat")
public class ChatController {

    // 채팅 메시지를 저장할 리스트를 생성
    private List<ChatMessage> chatMessages = new ArrayList<>();

    // 메시지 작성 요청을 표현하는 Record 타입을 정의
    public record writeMessageRequest(String authorName, String content) {
    }

    // 메시지 작성 응답을 표현하는 Record 타입을 정의
    public record writeMessageResponse(long id) {
    }

    // "/writeMessage" 엔드포인트로 POST 요청을 처리하는 메소드
    @PostMapping("/writeMessage")
    @ResponseBody
    public RsData<writeMessageResponse> writeMessage(@RequestBody writeMessageRequest req) {
        // 요청으로부터 받은 데이터로 ChatMessage 객체를 생성
        ChatMessage message = new ChatMessage(req.authorName, req.content);
        // 생성된 메시지를 채팅 메시지 리스트에 추가.
        chatMessages.add(message);
        // 클라이언트에게 응답을 반환. 메시지 작성 응답 Record를 생성하여 반환.
        return new RsData<>("S-1", "메세지가 작성됨", new writeMessageResponse(message.getId()));
    }

    // "/messages" 엔드포인트로 GET 요청을 처리하는 메소드
    @GetMapping("/messages")
    @ResponseBody
    public RsData<List<ChatMessage>> messages() {
        // 채팅 메시지 리스트를 응답으로 반환
        return new RsData<>("S-1", "성공", chatMessages);
    }
}

제네릭 클래스

@AllArgsConstructor
@Getter
public class RsData<T> {
    // 결과 코드를 저장하는 변수입니다.
    private String resultCode;
    // 메시지를 저장하는 변수입니다.
    private String msg;
    // 제네릭 타입의 데이터를 저장하는 변수입니다.
    private T data;
}
public class RsData<T>: 제네릭 클래스로, 제네릭 타입 T에 따라 데이터를 저장

제네릭 클래스란 클래스를 정의할 때 일반적인 형태로 만들지 않고, 특정한 타입에 의존하지 않고 여러 종류의 타입에 대해 동작할 수 있도록 하는 것입니다. 즉, 클래스 내부에서 사용되는 데이터의 타입이나 메서드의 인자, 반환값 등을 특정하지 않고, 클래스를 정의할 때 제네릭 타입을 사용하여 미리 지정하지 않은 타입을 사용할 수 있도록 합니다.

예를 들어, 위의 코드에서 RsData 클래스는 데이터를 저장하는 데 제네릭 타입 T를 사용합니다. 이는 RsData 클래스를 사용할 때 어떤 타입의 데이터든 저장할 수 있게 합니다. 예를 들어, RsData은 문자열을 저장할 수 있고, RsData는 정수를 저장할 수 있습니다.

제네릭 클래스를 사용함으로써 코드의 재사용성과 유연성을 높일 수 있으며, 타입 안정성(type safety)을 보장할 수 있습니다. 이는 컴파일 시에 타입 체크를 수행하여 타입 관련 오류를 미리 방지할 수 있도록 해줍니다.

그럼 모든 코드를 다 제네릭클래스로 짜면 편리할텐데 그렇게하지 않는 이유는 뭘까?

제네릭 클래스를 사용하는 것은 특정한 경우에 매우 유용하지만, 항상 모든 코드를 제네릭으로 만드는 것이 항상 좋은 선택은 아닙니다. 여러 이유로 인해 일반적인 클래스를 사용하는 것이 더 적절할 수 있습니다. 몇 가지 이유는 다음과 같습니다:

  1. 복잡성: 제네릭을 사용하면 코드가 더 복잡해질 수 있습니다. 제네릭을 사용하면 타입 안전성을 유지하기 위해 추가적인 타입 매개변수를 관리해야 하며, 이는 코드의 가독성을 저하시킬 수 있습니다.

  2. 성능: 제네릭은 일반적으로 실행 시간에 타입 소거(type erasure)라는 과정을 거칩니다. 이는 컴파일 시에 제네릭 타입 정보가 지워지는 것을 의미하며, 이로 인해 일부 성능 손실이 발생할 수 있습니다.

  3. 강력한 타입 체크: 제네릭을 사용하면 컴파일러가 코드를 더 강력하게 타입 체크할 수 있지만, 때로는 이것이 불필요한 제약을 가할 수 있습니다. 특정한 상황에서는 제네릭을 사용하지 않는 것이 더 유연할 수 있습니다.

  4. 코드 가독성: 제네릭을 오용하면 코드의 가독성이 저하될 수 있습니다. 특히 타입 매개변수가 많은 경우 코드를 이해하기 어려워질 수 있습니다.

따라서 코드를 작성할 때는 각 상황에 맞게 적절한 방법을 선택해야 합니다. 필요한 경우에만 제네릭을 사용하여 타입 안전성과 재사용성을 높이고, 간단한 경우에는 일반적인 클래스를 사용하여 코드를 간결하게 유지하는 것이 좋습니다.

profile
hello world

0개의 댓글