하루살이 개발일지

socket으로 실시간 채팅 구현하기 본문

웹개발/React

socket으로 실시간 채팅 구현하기

harusari 2024. 7. 15. 01:28

HTTP 통신

 

HTTP 통신이란 브라우저와 웹 서버가 통신할 수 있도록 규칙과 절차를 규정한 통신 프로토콜이다. HTTP 통신은 기본적으로 요청-응답 기반의 프로토콜인데, 하나의 컴퓨터에서 다른 쪽으로 Request를 하면 다른 컴퓨터에서는 이에 대응하는 Response를 돌려주는 방식이다.

 

이 방식은 많은 경우 합리적인 통신 수단이지만, 한계점도 존재한다. 두 컴퓨터 간 연결을 지속하는 대신 단발적으로 요청이 수신되었을 때만 연결을 허가하고, 응답까지 마무리된 후에는 연결을 해제하는 방식인 만큼 소규모 정보 전달이 다수 발생할 경우 계속해서 연결을 생성하고 해제하는 과정을 거쳐야 하며 이는 자원 낭비가 될 수 있다. 또한, 클라이언트 요청 없이 서버 쪽에서 먼저 클라이언트에 데이터를 전송하는 것이 불가능하다. 즉 HTTP 통신 프로토콜을 따르면, 모든 정보의 송수신의 시작은 클라이언트 쪽이 행동을 취함으로써 이루어질 수밖에 없다.

 

 

 

소켓(Socket) 통신

 

 


이러한 HTTP 통신의 단점을 보완하기 위해 소켓 통신이 사용된다. 소켓 통신은 클라이언트와 서버, 두 컴퓨터가 특정 포트를 통해 실시간으로 양방향 통신을 가능하게 만든다. 

 

소켓 통신에서는 각 컴퓨터가 독립적으로 데이터를 보낼 수 있는데, 이 과정은 각각 단방향 통신으로 이루어진다. 그러나 이 단방향 통신이 동시에 이루어지므로, 전체적으로 보면 양방향 통신이 가능하게 된다. 즉, 클라이언트와 서버가 모두 데이터를 보내고 받을 수 있기 때문에, 양쪽이 동등한 위치에서 통신을 주고받는다고 할 수 있다.


소켓 통신은 보통 다음과 같은 단계로 이루어진다:

  1. 서버 소켓 열기 : 서버는 특정 포트에서 소켓을 열고 클라이언트 연결을 기다린다
  2. 클라이언트 소켓 연결 : 클라이언트는 해당 서버의 IP주소와 포트를 사용해 소켓을 통해 연결을 시도한다
  3. 연결 수락 : 서버는 클라이언트의 연결 요청을 수락하여 소켓을 통해 연결을 설정한다
  4. 데이터 송수신 : 연결이 설정되면, 클라이언트와 서버는 열린 소켓을 통해 실시간으로 데이터를 주고받는다 (이 단계에서 양방향 통신이 가능)
  5. 연결 종료 : 통신이 끝나면 클라이언트와 서버는 소켓을 연결 종료하여 자원을 해제한다

소켓 통신은 HTTP 요청에서 연결을 소켓으로 업그레이드하고자 하는 요청을 주고받음으로써 시작된다. 두 컴퓨터 간의 상호 동의가 있다는 가정 하에, 소켓을 '여는' 작업과 그 열린 소켓에 '연결'하는 작업이 동반된다. 최초의 핸드셰이크 방식의 요청과 응답이 한 차례 오가면, 자유로운 소켓 통신이 열리게 된다.


구현 예시

프로젝트에 도입하고자 간단한 mvp만 구현해 보았다. (그래서 ui가 개구림)

일단 React Native와 nextjs로 웹앱 둘다 돌아가는 건 확인해 보았다. 그래도 웹 배포가 쉬우니 웹으로 사람들을 모아 테스트해보았는데,

 

 

 

뭐 대충 잘 되는 것 같았음..

물론 mvp라 정말 '실시간 채팅' 기능밖에 구현이 되지 않았는데 앞으로 소켓으로 해보고 싶은 건,

  • 사진 및 동영상 주고받기 (사용자가 사진을 첨부하면 서버에 사진을 업로드하고 url을 받아와 preview를 띄우면 될것 같음)
  • slack처럼 사용자가 입력 중이라면 입력 중 메시지 띄우기 (이건 textinput에 이벤트 걸어서 전달하면 될 것 같음)
  • 메시지 삭제
  • 실시간 사용자 참여 게임 app
  • 실시간 위치 공유하기

등등...

 

아맞다 서버는 aws로 배포하려다가 aws는 너무 복잡하다 🥲 아직도 IAM사용자가 뭔지 모를.. 그래서 heroku로 간단하게 배포했다. 처음에는 vercel로 하려다가 vercel은 소켓이 안된다는 것 같았음

https://vercel.com/guides/do-vercel-serverless-functions-support-websocket-connections

 

그래서 heroku로 간단하게 배포했다. vercel과 비슷한 느낌

 

 

프론트 github code

https://github.com/Haru-Im/socket-client/blob/main/app/chat/page.tsx

 

백엔드 github code

https://github.com/Haru-Im/socket-server