WebFlux + MongoDB + SSE 로 채팅만들기

2022. 9. 4. 01:04Spring

 

이번 시간엔

스프링 WebFlux와

NoSQL인 MongoDB 그리고

Server-Sent-Event, SSE 프로토콜을 이용하여 채팅 서비스를 만들어 보겠습니다.

 

WebFlux란?

Spring WebFlux는 Spring 5에 추가된 모듈로

Reactive-stack framework이며 Non-blocking에 reactive stream을 지원합니다.

적은 리소스로 효율을 극대화할 수 있다는 장점이 있습니다.

또한 스프링과 완벽하게 통합되며 비동기 non-blocking 메시지 처리가 가능합니다.

하지만 오류 처리가 복잡하다는 것과 자료가 부족하다는 단점이 있습니다.

MVC와 WebFlux를 같이 쓸 순 없습니다. 때문에 Spring의 Reactive Stack과 Servlet Stack 중 선택을 요합니다.

때문에 Spring MVC 애플리케이션을 WebFlux로 변환할 필요는 없습니다.

Reactive? Reactive Programming?

데이터 흐름과 전달에 관한 패러다임입니다.

우리가 주로 사용하는 명령형 프로그래밍(Imperative Programming)은 절차를 명시하여 순서대로 실행되는 반면

반응형 프로그래밍(Reactive Programming)은 데이터의 흐름을 먼저 선언하고 데이터가 변경되었을 때 연관된 작업이 실행되게 됩니다.

즉 기능을 직접 정해서 실행하는 것이 아닌 시스템 내에서 이벤트가 발생 했을 때 알아서 처리되는 것입니다.

 

SSE란?

HTTP 연결을 통해 클라이언트가 서버로부터 업데이트를 수신할 수 있는 서버 푸시 기술입니다.

소켓과 비교하였을때 리소스가 적게 든다는 장범이 있지만 동시 접속이나 브라우저에 대한 제한이 있어 애플리케이션의 특성에 따라 선택하여야 합니다.

 

이번엔  Kotlin으로 제작하도록 하겠습니다.

 

먼저 해당 사이트로 접속하여 MongoDB를 다운로드합니다. 

https://www.mongodb.com/try/download/community

 

MongoDB Community Download

Download the Community version of MongoDB's non-relational database server from MongoDB's download center.

www.mongodb.com

 

자신이 원하는 버전, OS 을 골라 Download를 받으시면 됩니다.

 

다운로드 후 실행하시면 

작업관리자에서 MongoDB가 실행 중이신 걸 확인하실 수 있습니다.

이후 다운 받으신 MongoDB의 폴더 안에 있는 bin 폴더까지 접속하여 시스템 환경 변수로 등록합니다.

C:\Program Files\MongoDB\Server\4.4\bin 

저 같은 경우 해당 경로로 되어 있습니다.

 

윈도 검색 -> 시스템 환경변수 편집 -> 시스템 변수에서 Path 더블 클릭 -> 새로 만들기 -> 해당 경로 등록

 

 

이후 스프링 프로젝트를 생성합니다.

Inteliij의 경우엔 New Project에서 바로 생성 가능합니다.

Spring Reactive Web (Web Flux), Spring Boot DevTools, Spring Data Reactive MongoDB를 dependencies로 추가합니다.

 

 

cmd ( 명령 프롬포트 ) 창을 여신 후 mongo를 입력하시면 mongoDB를 켜시고 접속하실 수 있습니다.

 

스프링 빌드가 완료 되면

application.yml 혹은 properties에 MongoDB의 정보를 입력합니다 

RDB와는 다르게 

DB driver source가 필요하지 않아 보입니다.

host 또한 기존 RDB 접속보다 쉽게 접근할 수 있습니다 

MongoDB의 기본 포트는 27017 포트입니다.

chatdb라는 DB에서 진행할 것이기에 database는 chatdb로 합니다.

 

이대로 실행하시면 자동으로 chatdb가 생성됩니다.

 

Document와 Repository를 만들어 보겠습니다.

RDB에서의 Entity와 동일하다고 보시면 됩니다.

Spring Data의 영역이기 때문에

Document의 필드명 그대로 함수로 녹여 손쉽게 데이터에 접근할 수 있습니다.

 

@Tailable 란?

Tailable은 MongoDB의 커서를 안 닫고 유지시킵니다.

즉 한건이라도 요청이 들어오게 되면 계속해서 그 커서를 유지시킵니다.

커서가 유지됨으로써 클라이언트는 계속해서 정보를 실시간으로 받을 수 있으며

다른 요청들의 결과들까지 바로 확인할 수 있습니다.

 

한번 직접 만들어보고 사용해보며 무슨 뜻인지 이해해보자.

 

우선 컨트롤러를 만듭니다.

getMsg()의 MediaType이 TEXT_EVENT_STREAM_VALUE가 걸려있습니다.

해당 미디어 타입이 SSE 프로토콜에서 사용되는 타입입니다.

 

 

잘 들어가는 것을 확인할 수 있습니다.

 

여기서 브라우저를 통해 접속한 탭을 확인해보면

계속해서 로딩 표시가 되어있는 것을 확인할 수 있습니다.

계속해서 요청과 응답을 주고받고 있다는 뜻입니다.

 

그 상태에서 바로 채팅을 하나 더 보내보면

 

여기서 엄연히 브라우저와 포스트 맨은 다른 클라이언트입니다.

하지만 이와 같이 포스트맨에서 보낸 요청이 브라우저에서도 바로 적용된 것을 확인할 수 있습니다.