모임의 호스트와 게스트간의 의사소통을 위해 채팅기능을 구현
HTTP Polling의 단점을 극복하기위해 WebSocket을 사용하여 채팅기능을 구현하였다.
Spring에서 지원하는 WebSocket 라이브러리를 사용하기위해 WebSocket을 추가해주고 WebSocket을 지원하지 않는 브라우저에서도 양방향 연결이 가능하도록 SocketJS의 의존성을 추가한다.
WebSocket http 프로토콜이 아닌 WebSocket프로토콜 인 ws
를 가지게된다. 또한 이에 대해 handshake를 연결하기 위해 임의로 endpoing를 지정해줄수있는데 프로젝트에서는 프로토콜과 같게 ws로 지정하였다.또한 앞서 추가한 SocketJS를 적용하기위해 withSockJs()
를 추가해주었다.
다음으로 WebSocket은 해당 연결된 모든 회원들의 채팅기능만 지원할뿐 각각 그룹별 채팅의 기능은 지원하지 못하는 한계점을 지니고 있기때문에 이를 해결하기 위해 STOMP
프로토콜의 pub/sub을 사용하여 각각 그룹별 채팅방을 생성할수있게 한다. 이때 각각의 pub과 sub에 대응하는 엔드포인트를 활용하여 그룹별 대상으로 발송하는 메세지를 분류할수있다.
MessageController는 앞서 설정한 ws 엔드포인트와 send 엔드포인트의 뒤이어 지정된 맵핑경로로 들어오는 메세지를 처리하는 로직으로 위 MessageMapping은 채팅방에서 메세지 입력시 이를 서버에 저장하고 이를 상대방에게 발송하는 로직의 controller를 구현한것이며
아래는 1대1채팅방에 입장했을때 상대방에게 알림이 가는 동시에 입장했다는 메세지를 발송하는 로직이다.
Scale-Out
전에는 단일 서버로만 운영되기 때문에 Spring이 지원하는 In-memory Broker
인 SimpleMessageBroker
를 사용하여 간단하게 구현하였으며 향후 서버의 Scale-Out
시에는 각기 다른서버의 회원들끼리는 채팅이 불가능하기 때문에 이를 해결하기 위해 기존 SimpleMessageBroker
를 외부 메세지 브로커 서비스인 RabbitMQ
를 사용한 서비스로 변경할 예정이다.
앞서 Controller에서 /room
의 엔드포인트로 발송된 메세지들은 브라우저의 stomp.subscribe()
의 함수로 지정된 경로로 받게된다.
또한 /send
의 엔드포인트로 시작하는 지정된 컨트롤러의 MessageMapping경로로 사용자가 입력한 메세지를 발송한다.