채팅앱을 설계하며 배운 내용

4 분 소요

클라이언트-서버 간의 통신 방식의 이해를 더하고 데이터가 어떻게 전달되는지 알아보기 위해 카카오톡이나 페이스북 메신저 같은 채팅방을 기반으로 채팅을 진행하는 안드로이드 앱을 만들어보려고 한다.

개발할 내용

  • 채팅 프로필 생성 기능
  • 채팅방 생성 기능
  • 친구 추가 기능
  • 1:1 채팅 기능
  • 단체 채팅 기능
  • 사진 보내기 기능
  • 채팅 내용 로컬 DB에 저장

기술 요건 검토

출처 : https://blog.sendbird.com/ko/자체-or-외주개발-카톡과-같은-메신저-어플을-개발하기

  • Server operation: Dedicated, IaaS (AWS, Azure, GCE), PaaS (Heroku, GAE)
  • Traffic handling: Load Balancing, Auto Scaling, Latency-based DNS routing
  • Database: No SQL (HBase, Cassandra, MongoDB), RDB (MySQL, Postgres)
  • File storage: Cloud storage, CDN
  • Cache: Redis, Memcached
  • Chat server: Proprietary, Open source, Commercial solution
  • Network layer: WebSocket, HTTP long-polling, TCP socket
  • Messaging protocol: 자체 프로토콜, XMPP, MQTT
  • Client platform: iOS, Android, Web (JavaScript), .NET, React Native, Ionic
  • 프로젝트의 성격/ 산업에 따라 요구되는 보안 정책을 준수하기 위해 추가적으로 마련해야 하는 보안/ encryption 기술
  • 기타: Logging, Monitoring, Analytics

위의 내용을 고려하여 어떻게 서비스가 구성될 수 있을지 고민해보기로 했다. 조사해보고 공부를 하다보니 몇 가지 방법을 이용하여 채팅앱을 만들 수 있다는 것을 알게 되었다.

WebSocket + Firebase

가장 간단하게 모바일 클라이언트 - 웹 서버를 연결할 때 사용했던 프로토콜은 HTTP 였다. 그러나 HTTP는 양방향 통신이 불가능하다. 즉, 한 유저가 채팅방에서 메시지를 전송했을 때 채팅방의 다른 사람들은 메시지를 읽어들일 수 없다는 뜻이다. 어떠한 클라이언트든지 채팅방에서 메시지가 발생했을때 이를 읽어들일 필요가 있었다. 이는 소켓 통신이나 롱폴링을 이용하면 실시간으로 양방향 통신이 가능하므로 해결되는 부분이었다. 필요에 따라 적절하게 소켓 통신과 롱폴링을 사용하면 된다. 하지만 이는 앱이 포그라운드에 있을 때만 유용하다. 특히 안드로이드 오레오부터는 백그라운드 서비스가 불가능해졌고 백그라운드에서 메시지를 받기 위해서는 별도의 푸시 메시지를 이용할 수 밖에 없게 됐다. (물론 편법으로 백그라운드 서비스에서 소켓을 열고 통신을 할 수는 있겠지만 굳이 그래야하나 싶다.) 그리고 백그라운드에서 소켓을 유지하거나 롱폴링을 사용하게 되면 배터리 소모의 이슈도 존재하게 될 것이 분명하다. 그러니 배터리에 효율적이고 현재 안드로이드 정책에 맞는 푸시 메시지를 이용하여 백그라운드에서 메시지를 전달받는 구조로 서비스를 개발해야 할 것 같다.

요약하자면, 간단하게 정리하여

안드로이드 포그라운드 - WebSocket, HTTP long-polling

안드로이드 백그라운드 - FCM

위와 같이 메시지를 서버와 주고 받을 수 있도록 만든다. 서버는 클라이언트에서 사용할 스펙에 따라 기술을 선택하여 구현하도록 한다. 구현하기에 앞서 각각의 기술이 어떤 기술들인지 간단하게 정리해본다.

양방향 통신 방법

polling

클라이언트가 평범한 HTTP Request를 서버로 계속 날려서 이벤트 내용을 전달받는 방식이다. 클라이언트가 주기적으로 요청을 하기 때문에 클라이언트 수가 증가하면 요청의 수도 함께 증가하기 때문에 서버의 부하가 커진다. HTTP Request 연결을 지속적으로 반복하는 것도 부하가 크다. 그리고 실시간으로 응답을 받기도 힘들다. 장점으로는 응답 간격을 일정하게 할 수 있는 것, 주기적으로 몰아서 물어보는게 가능하므로 자동으로 일괄처리를 할 수 있는 것이다.

long-polling

일정한 시간 간격을 두고 클라이언트에서 서버로 계속 요청을 보내는 polling 방식과 달리, 우선 클라이언트-서버 간 연결이 이루어지고 나서, 서버에서 이벤트가 발생할때까지 응답을 보류하다가 서버에서 클라이언트로 전달할 이벤트가 발생하면 그 순간 Response를 전달하며 연결이 종료된다. 클라이언트에서는 곧바로 다시 HTTP Request를 날려 서버의 이벤트를 기다리게 되는 방식이다. 일반 polling 방식보다는 서버의 부하가 줄겠으나 클라이언트로 보내는 이벤트의 간격이 좁다면 polling과 별 차이가 없게 된다. 다수의 클라이언트에게 동시에 이벤트가 발생할 경우 곧바로 다수의 클라이언트가 접속을 시도하기 때문에 서버의 부하가 급증한다.

streaming

일단 클라이언트에서 서버로 HTTP Request를 날린다. 서버에서는 해당 연결을 끊지 않고 필요한 메시지만 보내기를 반복한다. long polling에 비해 서버에서 메시지를 보내고도 다시 HTTP Request를 보내지 않기 때문에 서버의 부하가 줄어들 것이다.

WebSocket

메시지를 받기는 수월하나 전달하기는 불편하기 때문에 위의 방식들에서 벗어나 정식으로 클라이언트-서버 간 양방향 통신이 가능한 WebSocket이 HTML5 표준의 일부로 등장하게 되었다.

WebSocket이 TCP Socket과 다른 점은 최초 접속이 일반 HTTP Request를 통해 handshaking 과정을 통해 이루어진다는 점이다. HTTP Request를 그대로 사용하기 때문에 기존의 80, 443 포트로 접속을 하므로 추가적으로 방화벽을 열지 않고도 양방향 통신이 가능하고, HTTP 규격인 CORS적용이나 인증 등의 과정을 기존과 동일하게 가져갈 수 있다는 것이 장점이다.

XMPP + FCM

XMPP (Extensible Messaging and Presence Protocol)

2인 이상의 참여자 간에 구조적 데이터를 실시간에 가깝게 교환할 수 있게 해주는 XML 기반 TCP 커뮤니케이션 프로토콜. Pub/Sub 시스템도 사용되고 있다.

대부분의 대형 서비스가 채택하고 있는 구조로 위의 사진은 WhatsApp의 구조를 보여준다. XMPP를 구현하기 위한 ejabberd 서버를 사용하고 있다. 온라인 유저들만 XMPP를 통해 메시지를 전달하고 오프라인 유저들에게는 FCM/APNS를 통해 메시지를 전달할 수 있도록 만들어진 구조이다. 안드로이드 클라이언트에서는 SMACK을 통해 XMPP 메시지를 전달받을 수 있다.

안드로이드 포그라운드 - SMACK

안드로이드 백그라운드 - FCM

마지막으로

MQTT나 자체 프로토콜을 통해서도 채팅 앱을 만들 수 있다고 한다. 간단히 만들려면 Firebase만 이용해서도 만들 수 있다. 요즘 Firebase의 DB나 FCM이 매우 잘되어있기 때문에 가능해졌다. 옛날 C2DM, GCM 시절에는 유실되는 메시지가 너무 많아 문제였는데 기술의 발전에 따라 유실되는 메시지의 양이 줄어들어 가능해진 것 같다. 그럼에도 불구하고 다른 기술들과 섞어서 사용해야 완전한 유실을 막을 수 있다.

Firebase vs XMPP

https://www.techcronus.com/real-time-chat-application-development-xmpp-firebase/

두 방법 모두 간단히라도 구현해보면 좋을 것 같다. 일단 WebSocket을 이용해서 채팅 앱을 구현해보자.

출처

https://blog.sendbird.com/ko/자체-or-외주개발-카톡과-같은-메신저-어플을-개발하기

http://wink.egloos.com/v/4582028

https://www.androidpub.com/2114776

https://www.slideshare.net/hyogij/ss-46567833

[https://nekomimi.tistory.com/660](https://nekomimi.tistory.com/660) - [안드로이드] XMPP서버를 이용한 채팅앱 개발(그룹 및 단체)

https://okky.kr/article/293127

https://okky.kr/article/338303

https://medium.com/zaneiru-tech-life-blog/pub-sub-모델에-대해서-daa3c5c52aa8

[https://medium.com/@rlatla626/aws-elasticbeanstalk-node-js-socket-io-redis를-이용한-채팅서버-1-36d1dd5be62c](https://medium.com/@rlatla626/aws-elasticbeanstalk-node-js-socket-io-redis%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%B1%84%ED%8C%85%EC%84%9C%EB%B2%84-1-36d1dd5be62c) - AWS Elasticbeanstalk + Node.js + Socket.io + Redis를 이용한 채팅서버

[https://daddyprogrammer.org/post/4077/spring-websocket-chatting/](https://daddyprogrammer.org/post/4077/spring-websocket-chatting/) - Spring websocket chatting server

https://kamang-it.tistory.com/entry/Webhttp통신을-이용한-양방향-통신기법-long-polling

https://rationalowl.tistory.com/6

https://okky.kr/article/367996 - Websocket과 Stomp의 차이가 무엇인가요?

[https://adrenal.tistory.com/20](https://adrenal.tistory.com/20) - webSocket 으로 개발하기 전에 알고 있어야 할 것들

https://www.quora.com/Which-websocket-polyfill-Sockjs-Socket-IO-ENGINE-IO-is-best-suited-for-a-chat-application-that-involves-web-and-mobile-andriod-ios-clients-both-And-why

https://stackoverflow.com/questions/2681267/what-is-the-fundamental-difference-between-websockets-and-pure-tcp

https://medium.com/@thinkwik/web-sockets-vs-xmpp-which-is-better-for-chat-application-113e3520b327

https://www.quora.com/How-do-I-develop-an-Android-chat-app-using-XMPP

https://reddolphin.tistory.com/100 - 채팅앱 개발을 위해 자료조사를 하다 정리한 목록.

https://codeday.me/ko/qa/20190401/207142.html - java – 푸시 알림 용 XMPP 서버 및 Google Cloud Messaging (또는 최신 Firebase 클라우드 메시징)을 사용하여 Android 용 채팅 앱

https://www.techcronus.com/real-time-chat-application-development-xmpp-firebase/

https://aws.amazon.com/ko/blogs/database/how-to-build-a-chat-application-with-amazon-elasticache-for-redis/

https://cheesecakelabs.com/blog/simple-chat-architecture-mvp/

https://dzone.com/articles/build-a-chat-application-using-spring-boot-websock

https://alnova2.tistory.com/917

http://wkyoon77.blogspot.com/2014/01/xmpp.html - xmpp 서버 구축

https://yolongyi.tistory.com/31 - XMPP ?

https://medium.com/@sudarakayasindu/behind-the-scenes-of-chat-applications-38634f584758

댓글남기기