Skip to content

[DOC/CHAT] 채팅 통신 프로토콜에 대한 고찰 (WebSocket) #14

@Cassiiopeia

Description

@Cassiiopeia

💡 Description

Client - Server 통신 프로토콜에 관한 고찰

HTTP, SSE, WebSocket

이렇게 클라이언트와 서버간의 통신에는 대표적으로 3가지 종류가 있는데요 

HTTP, SSE, WebSocket이 있습니다.

HTTP

기본적인 개념에 대해서 보자면 HTTP 저희가 친숙한 프로토콜인데요.

클라이언트가 서버에 Request 요청을 보내고

서버가 응답을 Response 을 돌려주는 요청-응답 프로토콜입니다.

인터넷상의 데이터 교환의 기초라고 할수 있죠

클라이언트는 웹페이지를 요청하거나 form-data를 제출할때 HTTP요청을 보냅니다

서버에서 이 요청을 처리하고 결과를 클라이언트에 다시 주는데요

어떤식으로 작동하냐고 하면

먼저 클라이언트가 적절한 URL을 통해 서버에 접속하여 연결을 맺습니다.

저희는 GET, POST, PUT, DELETE 을 사용하여 서버에 데이터를 요청하게 되는데요 

서버는 이런 요청받은 메서드에 따라 안에서 요청을 수행합니다. 

Response 로 서버가 응답코드 200, 404 등 을 다시 클라이언트에 전송해줌으로써 연결이 종료됩니다.

HTTP 요청 메서드 종류

GET : 서버로부터 정보를 조회

POST: 서버에 데이터를 전송하여 새로운 자원을 생성

PUT: 서버의 자원을 업데이트

DELETE: 서버의 자원을 삭제

HEAD: GET와 비슷한 개념이지만 응답Body는 제외한 Header정보만 요청

OPTIONS: 대상 리소스에 대한 통신 옵션 정의

PATCH: 서버 자원의 부분적 업데이트(수정)

HTTP 응답 상태 종류

1xx: 정보적 상태코드 : 요청이 수신되어 처리중을 나타냄

2xx: 성공 코드 : 요청 성공적 수행

3xx: 리다이렉션 코드 : 요청을 완료하기 위해 추가 작업 필요함을 나타냄

4xx: 클라이언트 오류 코드 : 클라이언트 오류 요청 수행 불가

5xx: 서버 오류 상태 : 서버가 요청 수행 불가

지속연결 Persistent Connection / 파이프라이닝 Pipelining

: 지속연결은 클라이언트-서버와 요청/응답이 끝난 이후에도 연결을 종료하지않고 유지하는 방식입니다.

HTTP 요청과 응답이 연속적으로 이루어질때 매번 새로운 TCP연결을 생성하고 종료하지 않게 합니다.

연결설정에 소요되는 시간을 줄여서 로딩 속도가 빨라집니다

하지만 연결이 계속해서 유지되기때문에 서버의 자원을 계속 사용하고 사용되지않는 연결을 종료시키는 로직이 필요합니다.

: 파이프라이닝은 클라이언트가 여러 HTTP요청을 연속해서 보낼때 요청->응답반환 , 다음 요청-> 응답반환 이런식으로 응답반환까지 기다리는것이 아닌 

응답이 오기 기다리는동안 계속해서 다음 요청을 보낼수 있게 하는 기법입니다. 

하나의 요청에 대한 응답 기다리는 대기시간을 줄입니다.

SSE

Server-Sent Events 라는 SSE기술은 서버에서 단방향으로 클라이언트에게 실시간으로 데이터를 보내는 기술입니다. 

HTTP기반으로 해서 HTTP 보안 메커니즘을 그대로 사용합니다. 

애플리케이션에서 서버-> 클라이언트로 실시간 업데이트를 전송할때 사용합니다.

단방향이라는 큰 특징을 가지고있습니다. 

데이터는 서버에서 클라이언트로만 흐릅니다.

서버와 클라이언트의 연결을 열어두고 서버는 새로운 데이터가 있을때마다 데이터를 계속 보냅니다. 

표준 HTTP연결을 사용하고 데이터는 텍스트, JSON으로 인코딩하여 전송할수있습니다.

구현이 단순하고 연결이 끊기면 3초마다 재연결을 시도하며 스트림 이어받기 기능을 제공합니다.

이렇게 말하면 어디에 쓰이는지 잘 이해가 안될수도있습니다.

예시를 들어보면 생각보다 많이 사용할수있는 기술임을 알 수 있는데요.

주식화면에 들어가면 실시간 주식이 변동하는것을 볼 수 있습니다. 

SSE를 사용하여 클라이언트의 화면에서 차트, 대시보드가 변화하는것을 실시간으로 업데이트 할 수 있습니다. 

SNS에서도 게시글 피드가 새로 올라갔을때, 댓글이 추가됐을때 실시간으로 표시할수있습니다.

또 스포츠 경기 점수를 업데이트하는데 지도나 네비에서 사용자 위치변화, 실시간 교통상황표시에 사용할 수 있습니다.

SSE는 클라이언트에서 서버로 정보를 보내는 목적이 아닌 서버에서 정보를 받기만하는 상황에 적합한 기술입니다.

그러면 양방향으로 실시간으로 보내고 받으려면 어떤 기술을 써야할까요??

WebSocket

네 맞습니다. 

클라이언트과 서버간의 양방향 통신이 가능하게 하는 프로토콜은 WebSocket입니다. 

HTTP의 한계를 극복한

실시간으로 통신이 가능하며 지속적인 연결을 통해 데이터를 교환할 수 있게합니다.

HTTP연결을 통해 시작되며 Upgrade 라는 헤더를 사용하여 핸드쉐이크가 완료되면 

WebSocket 프로토콜로 변환합니다. 

연결이 한번 수립되면 계속 유지되고 추가적인 HTTP요청이 없이 데이터를 교환 할수있게합니다.

저희가 협업때 와이어 프레임을 볼때 사용하녀 UX/UI 디자인툴에 접속해있는 사람들의 커서가 뜨는것처럼

notion에서 각자의 수정사항이 실시간으로 표시되면서 작성하는 것처럼 

WebSocket은 저희가 계속해서 사용하고있었던 프로토콜입니다.

결론적으로 실시간으로 메시지를 교환하는 채팅을 구현을 하는데 적합한 프로토콜은  
바로 WebSocket이라 할수있습니다. 

이를 사용하여 1대1 채팅방을 구축하고 

메시지 저장을 MongoDB에 하면서 실시간 양방향 통신을 구현할 계획입니다.

SSE는 텍스트기반 메시지만 지원하는 반면에 웹소켓은 텍스트와 이진데이터를 모두 지원합니다. 

이미지 동영상 등의 파일을 스프링부트에서 @MessageMapping이라는 어노테이션을 사용해서 정의하면 

Byte[], ByteBuffer 형태로 전송할수있습니다.

하지만 저희 프로젝트에서는 AWS S3를 사용하여 데이터를 전송하기때문에 

이진데이터를 보내는 부분은 사용하지는 않을것같습니다. 

S3를 사용하면 미디어 데이터를 안전하게 저장할수있고 서버의 부하를 줄일수있습니다. 

예시))

HTTP
클라이언트 —-요청—> 서버

클라이언트 <—응답—- 서버
웹소켓
클라이언트 <–> 연결 유지 <–> 서버 (양방향 통신)
SSE
클라이언트 <—연결 유지— 서버 (단방향 통신)

image


🚗 Todo

  • WebSocket 설정파일 구현하기

🐶 Technology Stack

Spring WebSocket


## 📚 References

https://softwaremill.com/sse-vs-websockets-comparing-real-time-communication-protocols/

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions