WSGI - 동기(synchronous) 방식 (gunicorn)
ASGI - 비동기(Asynchronous) 방식 (daphne, uvicorn)
장고를 이용해서 chat-server, 주식과 같이 실시간 통신을 구현하게 된다면 보통 ASGI (비동기 방식) 을 사용하여 구성하는 것이 좋다.
만약 실시간 데이터를 받아야 하는 server에서 synchronous
방식을 사용하게 된다면, request가 처리될 때까지 또 다른 request 는 대기 하고 있어야 하므로 synchronous
방식보다는 Asynchronous
방식을 사용하여 빠른 응답과 동시에 여러 request 를 수행할 수 있다.
실시간 데이터를 주고받는 server 는 JavaScript 라이브러리인 Websocket 을 사용하여 실시간 통신을 구현한다.
Django 에서는 이 웹 소켓을 효율적으로 관리하기 위해서 Channels 라는 라이브러리를 통해서 실시간 채팅, 실시간 업데이트 와 같은 기능을 구현할 수 있다.
Channels 라이브러리를 사용하여 chat-server 를 구현하는 튜토리얼은 아래 링크를 통해 쉽게 작성할 수 있다.
튜토리얼 Part.1
튜토리얼 Part.2
튜토리얼 Part.3
튜토리얼 Part.4
튜토리얼을 클론 코딩을 하며 아래 Part.2 부분을 보자.
실시간 데이터를 주고받기 위해서는 "채널(Channel)"과 "그룹(Group)"을 활용하며, 이를 통해 ChatConsumer 인스턴스를 통해 다른 클라이언트와 통신할 수 있다.
또, 이러한 채널과 그룹을 사용하여 사용자들 간의 실시간 데이터 교환을 구현할 수 있다.
하지만 이와 같은 채널 레이어를 구현하려면 channels_redis 라이브러리를 사용하여 Django Channels와 Redis를 연결해야 한다.
Redis는 Django 의 백엔드 스토어로 활용되어 데이터를 저장하고 client 들에게 데이터를 뿌려주며 실시간 통신이 가능하게 된다.
튜토리얼에서는 docker 이미지를 통해 컨테이너에서 Redis 를 띄웠는데, 만약 docker를 사용하지 않는다면 Redis 를 직접 다운로드 받고, redis-server 를 실행해야 한다.
OS 별 Redis 다운로드 방법
- Windows :
https://github.com/tporadowski/redis/releases- Mac (Homebrew) :
$ brew install redis
- Linux :
$ sudo apt-get install redis
만약 Windows 환경에서 ASGI Websocket 을 runserver 로 테스트하게 된다면 'NOT Found: /ws/path/' 와 같이 오류가 발생하게된다.
그 이유는 runserver 는 ASGI Websocket 을 완전히 지원하지 않기 때문이다.
따라서, Windows 환경에서는 daphne 라이브러리를 통해서 ASGI Websocket 을 테스트해야한다.
$ daphne mysite.asgi:application --port 8000
보통 서버를 구성하게 되면 다음과 같이 동기/비동기 혼용 구성을 사용한다.
처음 클라이언트 요청이 오면 NGINX에서 요청을 받고 비동기 작업을 처리하기 위한 ASGI 애플리케이션을 실행해야 할 때는 Daphne 또는 Uvicorn 서버로, 동기 작업을 처리하기 위한 WSGI 애플리케이션을 실행하기 위해 Gunicorn 서버로 요청을 처리하게 된다.
Websocket & Channels 에 대해 공부할 때 봤던 유튜브 : https://youtu.be/cw8-KFVXpTE?si=LM5-goKNRaQ_hNWM