*위 글은 같은 팀원인 정광우행님의 채팅 서비스 구현 관련 글 기반으로 작성했습니다.
(광어 X🐟)
채팅 서비스
-설계
스터디 관리 웹 서비스 이음새 프로젝트는 전반적으로 스터디 관련 기능에 집중되어있다.
그래서 사용자 입장에서 고려했을 때, 추가적으로 있으면 좋을 만한 기능이 뭐가 있을까 고민하던 와중, 사용자 입장에서 불편한 상황이 떠올랐다.
웹 서비스 특성 상 스터디 게시자가 작성한 스터디의 소개글 이외의 정보를 얻기가 힘들다.
결국 스터디를 하려면, 스터디 일정을 잡아야되고 '일정 조율'이 핵심이다.
일정 조율을 위해선, 빠른 양방향 소통이 가능해야되고 그 포인트에서 바로 '채팅 서비스' 를 서비스에 추가하기로했다.
- 채팅방에 입장한다. (1:1채팅 / 그룹채팅)
- 입장했을 때 입장메시지가 채팅방에 출력된다.
- 메시지를 입력할 수 있는 입력란이 존재하고 그 옆에 ‘전송’ 버튼이 있다.
- 입력란에 메시지를 입력하고 ‘전송’ 버튼을 누른다. (Enter 키로도 가능)
- 내가 보낸 메시지가 보낸 즉시 채팅방에 출력되고 닉네임과 발신시간이 같이 출력된다.
- 다른 사람이 메시지를 보냈다면 내가 보낸 메시지는 받은 메시지의 위쪽으로 이동한다.
- 다른 사람이 보낸 메시지에 상대방의 닉네임과 발신시간이 포함되어있다.
- 최신 메시지가 가장 하단에 쌓이고 채팅방의 영역을 벗어날 만큼 메시지가 생성되었다면 스크롤이 생겨 이전 메시지를 볼 수 있게 한다.
- 브라우저를 종료하거나 다른 페이지를 갔다 와도 이전에 주고 받았던 메시지는 남아있다.
위처럼 두서는 다소 없더라도 순서도 시나리오를 대충 구상했다고 한다.
같이 프로젝트를 진행하며, 부실한 설계를 했었다고 그로 인한 문제점들이 많이 발생했다.
그 이후로 ,설계의 중요성을 우리 팀 모두 절실히 깨달았기때문에 ,좋은 설계를 기반으로 진행하는 개발자가 되어야겠다!
1. 아키텍처 패턴: Publish - Subscribe Pattern
Def Architecture Pattern : 시스템의 기본 구조적 조직을 표현하는 재사용 가능한 솔루션
본격적으로 채팅 서비스를 설계하기 앞서 아키텍처 패턴을 반드시 먼저 정하는 것이 좋다.
아키텍처 패턴은 쉽게 말하면 시스템 전반적인 구조의 컨셉을 정하는 것이다.
특히 복잡한 시스템을 개발할 때는 아키텍처 패턴을 바탕으로 설계를 진행하는 것이 확장성, 성능, 유지보수 등 여러가지 측면에서 큰 장점을 갖게 해준다.
즉, 앞서 같은 프로젝트를 진행했던 사람이 ‘~~한 순서로 하니까 나중에 좋더라” 라는 조언을 미리 듣고 순서에 맞게 진행하는 느낌이다.
- 발행-구독 패턴
- 웹소켓 기반 실시간 통신
- 클라이언트-서버 모델: 확장성 제한적, 실시간 성능 부족
- 마이크로서비스 아키텍처: 복잡도 증가
채팅 서비스의 아키텍처 패턴 중 발행-구독 패턴을 선택했다.
그 이유는 발행-구독 패턴의 가장 큰 장점이 실시간 성능이 좋고 확장성이 좋기 때문이다.
또한 메시지 라우팅이나 구독/발행 모델 등이 이미 구현, 추상화가 되어있다. 그리고 코드를 미리 보았을 때, 학습 곡선이 높다고 생각되지 않아서 처음 개발하는 사람도 구현이 가능할 것이라고 생각했다.
실질적으로 내가 발행-구독 패턴을 선택한 가장 큰 이유는 1:1 채팅과 그룹 채팅의 구분을 명확하게 하지 않아도 된다는 점이었다.
발행-구독 패턴의 가장 큰 특징은 특정 topic을 구독한 사람들이 같은 채팅방에서 실시간으로 채팅을 할 수 있게 만들어 준다는 것이다. 이는 즉 topic을 구독한 사람이 2명이라면 1:1 채팅방, 3명 이상이라면 그룹 채팅방이 되는 것이다.
즉, 내가 채팅방에 관련된 로직 하나만 만들고 특정 주제로 접근하는 방식만 달리 해주면 코드의 재사용성이 월등히 높아질 수 있다.
2. Protocol: WebSocket
Def WebSocket : TCP 연결을 통해 전이중, 양방향 통신 채널을 제공하는 컴퓨터 통신 프로토콜
정의만 놓고 보면 어렵게 느껴지지만 쉽게 설명하면 기존의 HTTP의 단방향 통신 방식에서 좀 더 업그레이드 되어 양방향으로 통신이 가능하도록 만든 것이다.
작동 방식은
- 초기 연결: HTTP handshake를 사용하여 연결을 시작
- 업그레이드: 연결이 WebSocket 프로토콜로 ‘업그레이드’ 된다.
- 양방향 통신: 연결된 후에도 클라이언트와 서버가 자유롭게 메시지를 주고 받을 수 있다.
이렇게 되는데 깊게 들어가면 과하게 복잡해서 간소화했다. 이 중 중요한 점은 ‘양방향 통신’ 인데 일반적으로 우리가 생각하는 채팅 서비스는 모두 ‘실시간’과 ‘양방향 통신’의 특징을 갖고 있다. 나는 채팅 서비스를 구현할 때 가장 신경 써야 하고 중요하게 생각한 점이 이 두 가지 개념이기 때문에 WebSocket 프로토콜 방식이 적합하다고 생각했다.
그 외에 다른 여러 방식들이 있다.
- HTTP Long Polling
- Server-Sent Events
그렇지만 대부분의 경우 단방향 프로토콜이거나 실시간성이 떨어진다. 또한 현재 WebSocket은 웹 표준이며 대부분의 브라우저와 서버에서 지원된다. 이러한 장점들 때문에 통신 프로토콜은 WebSocket을 선택했다.
3. Messaging Protocol - STOMP
Def STOMP : 간단한 텍스트 기반 메시징 프로토콜로, 웹소켓 위에서 동작하는 하위 프로토콜
STOMP(Simple Text Oriented Messaging Protocol)는 쉽게 설명한다면 웹소켓을 사용하는 기법 중 하나이다. 주로 클라이언트와 메시징 브로커 간의 비동기 통신을 위해 설계되었다.
이 브로커를 통해서 클라이언트 → 서버 / 서버 → 클라이언트의 메시지 전달을 원활하게 하고 명확하게 식별하여 발신자와 수신자의 채팅방 메시지 구역 분리 등의 기능을 쉽게 설정할 수 있다.
또한 발행-구독 패턴과의 호환성이 좋아 복잡한 코드 없이 간단하게 설정 클래스를 통해 기능을 구현할 수 있다.
4. 채팅 서비스의 원리
채팅 개발을 처음 접한다면 위의 용어들이 어렵다. 난생 처음 들어보는 엔드포인트와 주제, 구독 등의 용어 때문에 간단한 문장이라도 여러 번 읽고 반복해야했다. 그래서 나중의 나를 위해 용어를 최대한 상세하고 자세하게 정리했다.
첫 번째는 @Configuration 어노테이션을 사용하는 Config라는 설정 클래스 자체의 존재이다.
기존에 진행했던 기능들에 관해서는 설정 클래스를 만든 적이 없고, 대부분 수동으로도 충분히 진행이 가능했다.
그래서 Config라는 클래스에 대해 반드시 존재해야 하는 지에 의문이 들었다.
그래서 다른 사람들의 코드를 학습하고 검색을 수차례 해본 결과 초보인 내 눈에도 보일 만큼 코드의 가독성에서의 차이를 찾을 수 있었다.
Config 클래스가 없을 경우 WebSocket이라는 기능 자체에 세부적인 부분들을 전부 다 수동으로 해야하고 javax.websocket.API와 같은 라이브러리를 사용해서 서버를 설정하고 엔드포인트와 메시지 라우팅을 직접적으로 처리해야한다. (이 같은 방식을 웹소켓 기반 실시간 통신이라고 한다.)
이는 프로젝트가 진행될 수록 코드의 가독성과 유지보수성을 현저하게 저하시킬 수 있다.
그래서 WebSocketConfig라는 설정 클래스를 중앙 제어 장치로 활용하여 간단하게 어노테이션이나 주소를 이용하여 필요할 때만 사용할 수 있게끔 만들었다.
나도 로그인 기능을 구현할 때 Spring Security 를 쓰며 Config라는 설정 클래스를 이용하였는데,
'중앙 제어장치' 라는 워딩이 와닿았다.
두 번째는 end-point이다.
엔드 포인트는 웹소켓의 특수한 기능은 아니고 네트워크 프로토콜과 메시징 시스템에서 공통적으로 사용되는 개념이다.
그렇지만 웹소켓과 같은 실시간 통신을 다룰 때 특히 유용하게 사용된다.
엔드포인트는 클라이언트가 서버와 웹소켓 연결을 맺기위해 사용되는 URL이다.
처음 채팅방에 들어가면 내부적으로는 WebSocket 엔드포인트로 접속이 되어 실시간으로 통신이 가능하게 만들어준다. 예를 들면 ‘ws://example.com/ws-endpoint’ 의 형태로 접속이 되는데 헷갈리면 안되는 점은 클라이언트의 화면에는 이 주소가 나타나지 않는다. 이 주소는 내부주소로 Spring WebSocket과 이후 만들어질 JS에서 웹소켓 연결을 설정할 때 사용하는 주소이다.
이 주소는 현재 WebSocketConfig 클래스와 이후 const socket = new SockJS('/ws-endpoint'); 의 형태로 JS에서 사용되는 것 외에는 더 이상 사용되지 않는다.
단순하게 ‘인터넷 연결을 한다.’ 정도로의 의미로 이해하고 ‘연결이 끊어지면 채팅 기능이 실시간으로 이루어지지 않는다.’ 정도로 이해해도 실제 서비스를 구현하는데 문제는 없다.
🤔 엔드포인트는 내가 아는 개념상으론 API의 지점이라고 생각을 했다. 예를 들어, 나는 회원 정보를 api.users/info로 담았고, 이 엔드포인트로 호출을 하면 응답하는 형태로 로직을 짰다. 위에서는 ' 네트워크 프로토콜과 메시징 시스템에서 공통적으로 사용되는 개념' 이렇게 표현을 해서 이 차이점에 대해서 자세히 알아봐야겠다.
엔드포인트라는 용어는 문맥에 따라 다르게 해석될 수 있다
API 엔드포인트와 WebSocket 엔드포인트는 서로 다른 통신 방식과 목적을 가진 개념
API 엔드포인트는 HTTP 요청-응답 구조를 기반으로 하여 데이터를 주고받는 데 사용되며, 비지속적인 통신을 특징.
반면, WebSocket 엔드포인트는 실시간 양방향 통신을 가능하게 하는 지속적인 연결을 설정하는 데 사용.
이 두 가지 개념을 혼동하지 않고 상황에 맞게 적절히 사용하는 것이 중요!
세 번째는 topic이다. 주제라고 부르는데 주제는 메시징 시스템에서 메시지를 발행하고 구독하기 위한 논리적 채널이다.
엔드 포인트는 사용자간, 사용자와 서버간의 접속 자체를 의미한다면 주제는 더 좁은 범위로 채팅방을 식별하는 URL이며 메시지를 주고 받는 구분이다.
다만 특이한 점은 STOMP 자체가 메시지를 전달하는 방식이 브로드캐스트 방식이라 메시지를 전송하면 특정 주제를 구독한 모든 사용자에게 메시지가 전달된다.
이러한 방식이 일반적으로 많이 사용하는 실시간 채팅 방식이며 내가 채팅 서비스를 만들 때 STOMP 방식을 선택한 이유이기도 하다.
예를 들어 /topic/chat 이라는 주제를 구독한다면 해당 주제를 구독한 사람이 몇 명이든지 메시지를 전달할 수 있다.
단점이라면 특정 인물에게만 보내고 싶을 때는 새로운 주제로 메시지를 발송해야 하므로 불편함이 존재하지만 어차피 1:1 채팅과 그룹 채팅을 같이 만들 목적이었기 때문에 단점으로 작용하지는 않았다.
이후에 더 다루겠지만 주제를 설정하는 부분에서 고민이 많았다.
1:1 채팅은 /topic/chat , 그룹 채팅은 /topic/groupChat 식으로 처음에는 주제를 통해 채팅 간의 구분을 명확하게 하려 했으나 이후 가독성이 다소 떨어지고 몇 번의 시행착오를 겪었다.
복잡한 서비스를 구현하려는 것이 아니기 때문에 /topic/chat 주제 하나로 묶어 단순하게 만들었고 채팅방 간의 구분은 /topic/chat/{chatIdx} 형식으로 chatIdx를 다르게 주고 ChatType이라는 속성을 추가해 PERSONAL 과 GROUP 으로 구분했다.
이는 어떤 방식이 더 효율적이고 좋은 방법인지 까지는 모르겠지만 현재로써는 통합해서 만드는 게 소규모 프로젝트에서는 더 간편한 방법이라고 말할 수 있다.
추가적으로 특정 유저에게 SimpMessagingTemplate 를 이용하여 해당 유저의 정보를 통해 메시지를 전송할 수 있는 기능이 있지만
이렇게 보낼 바에는 차라리 채팅방을 새로 만들어서 둘 만 이용할 수 있도록 만들어 주는 것이 현재 서비스 기준에서는 더 효율적이라고 판단했다.
나도 로그인 기능을 구현할 때, 막연히 고도화된 기술에 매료되었던 적이 있었다.
하지만 중요한 것은 '우리 프로젝트에 어떤 기술이 적합한지' 에 대해 먼저 판단하고 사용하는 것임을 깨달았다.
네 번째는 구독(Subscribe)의 개념이다.
구독은 클라이언트가 특정 주제를 통해 메시지를 받기 위해 메시징 시스템에 요청하는 행위를 말한다.
쉽게 말하자면 클라이언트 입장에서 ‘난 이 채팅방의 메시지를 받겠습니다.’ 라고 동의를 하는 행위이다.
구독의 동작 과정은 특정 주제를 구독하겠다는 요청을 서버로 보내면 이를 메시지 브로커나 웹소켓 서버에서 처리하고 요청을 받아들여 구독자로 등록한다.
이렇게 하면 과정이 많아 보이고 다소 복잡해 보일 수 있지만 실생활에 비유를 해보자면
'잡지를 구독한다고 했을 때 잡지 출판 회사에 구독신청을 하고 구독 신청이 완료되면 출판 회사에서는 새로운 잡지가 출판될 때마다 구독 신청을 한 사람에게 모두 잡지를 발송한다.'
이와 같은 개념으로 특정 주제를 구독하면 채팅방에서 메시지가 생성되었을 때 구독한 사람 모두에게 메시지를 전송한다.
구독의 장점은 하나의 주제로 여러 사용자를 관리할 수 있고 구독자 수에 관계없이 확장성이 뛰어나다.
다만 구독 시스템을 처음 설정하고 관리하는데는 일정한 복잡도가 따르고 주제가 많아지면 구독 관리가 점점 복잡해진다.
또한 구독 서비스 특성상 구독이 유지되는 성질을 가지고 있어 대규모의 사용자가 구독을 하면 네트워크 트래픽이 증가하여 부하가 발생할 수 있다.
그래도 해당 프로젝트의 경우 부하가 걸릴 만큼의 규모도 아니고 disconnect()와 unsubscribe() 를 적절하게 사용하여 리소스 사용을 줄이고 연결을 관리하여 네트워크를 원활하게 만들 수 있다.
적혀있는대로, 주제가 많아진다 가정하면
다섯 번째는 애플리케이션 목적지 접두사이다.
애플리케이션 목적지 접두사는 클라이언트가 서버로 메시지를 전송할 때 사용하는 경로의 접두사를 정의한다.
이를 통해 클라이언트가 보내는 메시지가 서버의 특정 핸들러로 라우팅된다.
특정 핸들러란 Controller 클래스의 @MessageMapping 어노테이션을 가지고 있는 메소드를 말하고 해당 메소드로 라우팅(경로설정) 후 메시지를 처리한다.
또한 config.setApplicationDestinationPrefixes("/app"); 라고 설정이 되어 있으면 @MessageMapping("/chat.sendMessage") 이 붙어있는 주소에는 자동적으로 접두사로 "/app" 가 붙는다.
즉 전체 주소는 ("/app/chat.sendMessage") 이지만 이 또한 자동적으로 생략되어 "/chat.sendMessage" 만 작성해도 문제가 없다. 이 같은 기능들을 대신 수행해주는 것도 Config 클래스를 만드는 장점 중 하나이다.
마지막으로 메시지 브로커는 Config에서 확장한 WebSocketMessageBrokerConfigurer 의 메소드 중
configureMessageBroker 로 설정할 수 있다.
웹소켓을 통해 클라이언트와 서버 간의 메시지를 관리하고 전달하는 역할을 하는 중개자이다.
클라이언트가 메시지를 전송하면 바로 다른 클라이언트에게 보여지는 것이 아니라 서버로 먼저 전달된다.
그러면 서버에서는 포맷팅을 하거나 DB에 저장하거나 하는 등의 과정을 거치고 해당 주제를 식별하고 주제를 구독하고 있는 클라이언트들을 식별한다. 그리고 나서 다시 클라이언트 측으로 메시지를 전송한다.
이 과정에서 서버에서 클라이언트로 메시지를 전달할 때가 브로커의 역할이다. config.enableSimpleBroker("/topic");는 메시지 브로커가 관리하고 처리할 주제를 지정하는 메소드이다.
해당 주소로 어떠한 요청이 발생했을 때는 메시지 브로커가 각 주제에 맞게 처리한다.
사실상 위의 6가지의 개념을 확실하게 이해한다면 이후 다루는 코드들의 경우 일반적인 Spring 프로젝트에서 쓰이는 MVC 기반의 개념들이다.
* 내부 동작 원리가 어떻게 되는지 알아보자.
정리
2. 클라이언트는 페이지 로드 시 WebSocket 연결을 시도한다.
3. 연결이 성공하면, 클라이언트는 특정 주제(/topic)를 구독한다.
- 입장’ 버튼에 주제(topic)을 넣어두고 사용자가 눌러서 접속하면 자동으로 구독
4. 사용자가 채팅방에 입장하면, 클라이언트는 입장 메시지를 채팅방에 출력한다.
5. 서버는 입장 메시지를 받아 모든 구독자에게 브로드캐스트한다.
6. 사용자가 메시지를 입력하고 전송하면, 클라이언트는 이를 서버로 전송한다.
7. 서버는 메시지를 받아 처리하고, 다시 모든 구독자에게 브로드캐스트한다.
8. 구독 중인 모든 클라이언트는 메시지를 받아 화면에 표시한다. ⇒ 발행-구독 패턴을 통해 메시지의 효율적인 라우팅이 가능해지고, STOMP 프로토콜을 사용함으로써 메시지의 형식과 처리 방식이 표준화 된다

클라이언트가 채팅방에 접속했을 때, /ws-endpoint 라는 내부주소를 통해 서버와 클라이언트간 양방향 통신 채널이 열린다. 이 엔트포인트는 클라이언트가 접속을 종료할 때 까지 유지된다.

접속이 연결됐다면 자동으로 주제 /topic 을 구독하게 된다.

그림을 이해하기 위해 중요한 2가지를 말하자면,
- 클라이언트 → 서버: /app 접두사 사용
- 서버 → 클라이언트: /topic 접두사 사용
메시지를 전송하는 과정은 처음 클라이언트가 메시지를 입력하고 전송을 하면 sendMessage()라는 JS에서 정의한 메소드가 실행된다.
이 메소드는 채팅 /app 접두사를 가지고 sendMessage()라는 메소드를 호출한다.
그러면 메시지는 @MessageMapping("/chat.sendMessage/{chatRoomId}") 에노테이션을 가진 Controller로 라우팅된다.
그 다음, Controller에서 서비스 로직을 수행한 후, @SendTo("/topic/chat/{chatRoomId}") 어노테이션을 가진 주제로 메시지를 전달한다. 그러면 해당 주소로 가서 displayMessage()를 호출하여 채팅방에 메시지를 출력해준다.
-추가적으로 @MessageMapping("/chat.sendMessage/{chatRoomId}") 에서 @MessageMapping 어노테이션은 /app 접두사를 생략한다. 그래서 원래의 주소는 /app/chat.sendMessage/{chatRoomId} 이 맞다. 그렇지만 생략되었기 때문에 굳이 쓸 필요는 없다.
5. 구현
이제부터 실제 Spring Boot를 이용해 채팅 서비스를 구현해보겠다.
가장 먼저, 엔드포인트와 주제, 브로커, 애플리케이션 목적지 접두사 등을 설정할 WebSocketConfig 클래스를 작성해보겠다.
package com.ieumsae.chat.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker // 웹소켓과 STOMP를 사용하기 위한 설정 클래스
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
/**
@WebSocket 연결을 위한 엔드포인트를 등록
@AddEndpoint 웹소켓 연결을 시작할 때 사용할 URL 경로
@withSockJS() 웹소켓을 지원하지 않는 환경에서도 실시간 통신이 가능하게 함 (버전이 낮은 브라우저)
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-endpoint").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
// 메시지 브로커를 구성
config.enableSimpleBroker("/topic");
// topic 주제에 대해 메시지 브로커를 사용하도록 설정
// 클라이언트가 이러한 접두사로 시작하는 주제를 구독하면, 해당 주제로 전송된 메시지를 받을 수 있다.
// 메시지를 받을 때
config.setApplicationDestinationPrefixes("/app");
// 메시지를 전송하면 자동으로 주소 앞에 /app이 붙는다. => @MessageMapping 이 적용된 컨트롤러 메소드로 라우팅
// 클라이언트에서 서버로 메시지를 전송할 때 사용할 접두사를 지정
// 메시지를 보낼 때
}
}
위의 WebSocketConfig 클래스는 채팅 서비스에서 가장 중요한 부분이기 때문에 한 줄씩 나눠서 정리해보자.
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
- @Configuration은 Spring의 설정 클래스 임을 나타낸다.
- @EnableWebSocketMessageBroker는 WebSocket 메시지 브로커를 활성화한다. 이를 통해서 실시간 양방향 통신이 가능해진다.
- WebSocketMessageBrokerConfigurer 인터페이스를 구현한다. 이 인터페이스는 WebSocket 및 메시지 브로커 설정을 위한 메소드를 제공한다.
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-endpoint").withSockJS();
}
- WebSocketMessageBrokerConfigurer 에서 제공하는 메소드 중 registerStompEndpoints를 오버라이딩 한다. 이 메소드의 주 역할은 WebSocket의 엔드포인트를 설정한다.
- 매개변수인 StompEndpointRegistry는 STOMP 통신을 위한 end-point를 등록하는데 사용되는 인터페이스이다.
- registry.addEndPoint("/ws-endpoint”)는 클라이언트가 WebSocket 연결을 시작할 때 사용할 URL 경로이다. 즉, 소켓 연결을 할 때 필요한 내부 주소다.
- withSockJS(); 는 WebSocket을 지원하지 않는 브라우저에서도 통신을 가능하게 하는 폴백 옵션을 제공한다.
- Fallback option: 주요 기능이나 기술이 사용 불가능일 때 대체 방법을 제공하는 메커니즘
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
- WebSocketMessageBrokerConfigurer 에서 제공하는 메소드 중 configureMessageBroker를 오버라이딩 한다. 이 메소드의 주 역할은 브로커를 구성한다.
- config.enableSimpleBroker("/topic");는 /topic 접두사로 시작하는 주제에 대해 메모리 기반의 메시지 브로커를 활성화한다. 즉, /topic으로 시작하는 주소에 접속하면 채팅을 위한 WebSocket 연결이 활성화 되는 것이다.
- config.setApplicationDestinationPrefixes("/app"); 는 /app 접두사를 애플리케이션 목적지 접두사로 설정한다. 클라이언트가 서버로 메시지를 보낼 때 이 접두사를 사용한다. 또한 /app 으로 시작하는 메시지는 @MessageMapping이 적용된 컨트롤러 메소드로 라우팅 된다.
🙇♂️ 결론
프로그래밍의 기본은 협업이다. 물론 작은 규모의 토이 프로젝트 경우는 혼자 만들 수 있겠지만, (사실 못 만듦)
결국 현업의 세계는 무조건 협업이다.
사실 첫 프로젝트를 진행하면서 사실 협업의 느낌을 강하게 받진 못하였다.
각자 다들 미숙하다보니 초기환경 세팅도 같이 진행하지 않았고, 다양한 이야기들도 나누지 못했고, 거의 협업을 가장한 분업이였다.
그래도 팀원들과 같이 다시 처음 단계로 돌아가 테이블 설계, GIthub 세팅 등 우리가 해야할 것들을 다시 되짚어보았다.
초기환경 세팅에 대한 공부도 하고, 지식 공유도 하며 정말 같은 팀으로 협업하는 느낌을 받았다.
지식 공유만으론 모든 걸 이해하기에는 당연히 어렵다. (나중에 직접 구현하며 모르는 점들 물어봐가면서 하면 좋을 듯!!)
다음 프로젝트 때 보다 더 좋은 설계와 기본기를 바탕으로 프로젝트를 진행해야겠다.
마지막으로, 첫 프로젝트부터 마음이 잘 맞는 좋은 팀원들을 만나 너무 좋다!
덕분에, 프로젝트를 떠나 내 인생에 있어서도 많은 성장을 했다.
다음에도 꼭
좋겠진 않고 더 잘하는 사람을 만나서 캐리 받고 싶다!! 는 농담~ ㅎ

'Project' 카테고리의 다른 글
[nawanolja] Architecture 파악하기 . (0) | 2025.03.19 |
---|