필요해서 정리해본다.
Django3는 asynchronous view 나 middleware를 지원하지 않는다. 하지만 Django Channels를 사용하면 연결과 소켓을 비동기적으로 처리하는 것이 가능하다.
<참고>
https://channels.readthedocs.io/en/latest/index.html#django-channels
https://victorydntmd.tistory.com/261
요구되는 functionality는 서버와 클라이언트 사이의 리얼타임 커뮤니케이션이다. ASGI를 통한 비동기통신을 사용해서 채팅서버를 구현할 것이다.
Django는 HTTP request를 핸들링하기위해 보통 WSGI로 deploy되지만 Websocket request를 핸들링하기 위해 ASGI를 이용할 것이다. ASGI는 WSGI를 계승한 것으로 HTTP/2, Websocket 같은 프로토콜을 지원한다. ASGI는 비동기 요청인 웹 소켓을 처리하는 이벤트로써 connect, send, receive, disconnect를 가진다.
- WSGI (Web Server Gateway Interface)
이는 파이썬을 위해 만들어진 것으로 파이썬 스크립트가 웹 서버와 통신하기 위해 만들어진 인터페이스다. 웹서버의 요청을 해석하여 파이썬 응용프로그램에 던지는 역할을 수행한다.
The request/response cycle using channels
standard synchronous request cycle 과 Channels implementation과의 차이를 비교한다.
브라우저는 request를 보내고 Django 는 브라우저로 돌려보낼 response를 담은 view를 호출한다. 전형적인 synchronous Django setup의 도해이다. 연결된 HTTP 요청 없이 open connection을 유지하거나 브라우저에 데이터를 보내는 메커니즘이 없다.
Channel을 사용하면 request/response cycle의 컨셉에 변화가 생긴다. 채널은 Django로 하여금 HTTP view와 유사한 방식으로 웹소켓을 지원한다. HTTP request는 여전히 동일한 방식으로 작동하지만 채널을 경유한다.
즉 채널은 채널을 관통해 보내진 메세지로 Django request/response cycle을 대체한다.
channels package 구성
- Channels : 장고 통합레이어
- Daphne: HTTP와 Websocket용 종단서버(terminal server)
- asgiref: 기본 ASGI library
- channels_redis : Redis활용한 채널레이어 백엔드
Turtles All the way down
consumers는 채팅메시니나 알림등을 처리하는 독립적인 요소이다. channels는 기본적인 consumers를 작성하고 URL routing에 연결하고 프로토콜을 감지하는 등의 기능을 제공한다. (consumers를 동기적방식의 장고에서의 views.py라고 보아도 무방?하다)
HTTP와 기존의 장고 어플리케이션을 구성요소로 사용하는 것이 가능하다. 장고 뷰를 섞어 쓰면서 필요할때 비동기도구를 사용할수있다.
Scopes와 이벤트
channels와 asgi는 들어오는 연결을 두개의 컴포넌트로 분리하는데 하나는 스코프이고, 다른 하나는 이벤트들의 리스트이다.
스코프는 하나의 들어오는 연결에 대한 상세설명의 집합이다. 요청이 발생한 URL, 웹소켓이 열린 ip주소, 유저정보등으로 구성되며 연결이 종료될때까지 유지된다.
HTTP의 경우에 스코프는 하나의 요청동안만 유지되고 웹소켓의 경우엔 스코프는 소켓의 수명 전체에 걸쳐서 유지된다.
HTTP example:
- 유저가 HTTP request를 보낸다.
- HTTP의 타입 스코프를 요청 URL, method, header 등을 담아 만든다.
- http.request 이벤트를 HTTP body에 담아 보낸다.
- channels or asgi application이 이것을 처리해 http.response 이벤트를 생성하고 브라우저에 응답하며 연결이 종료된다.
- HTTP 요청/응답이 완결되고 스코프가 삭제된다.
챗봇 example:
- 유저가 챗봇에게 첫번째 메세지를 보낸다.
- 그러면 유저의 ID, 이름, 유저명 등이 담긴 스코프를 만든다.
- 어플리케이션이 chat.received_message이벤트를 텍스트 데이터와 함께 받는다. 이에 꼭 응답할 필요는 없지만 원한다면 하나나 그 이상의 챗메세지를 chat.send_message의 이벤트 형태로 전송할 수 있다.
-유저가 챗봇에게 메세지들을 수차례 전송하면서 그만큼 chat.received_message이벤트들일 더 생성된다.
- 제한시간이 지나거나, 어플리케이션 프로세스가 재시작되면 스코프가 닫힌다.
스코프의 수명주기동안 스코프안의 모든 이벤트를 처리하는 하나의 어플리케이션 인스턴스를 만들고 관련 데이터를 그 위에 유지해야한다. 이러한 작업을 수행하는 asgi application을 직접 만들수도 있겠지만 channels는 그런 일을 해주면서 쉽게 사용이 가능한 추상화된 요소를 제공하는데 그것이 consumers다.
요청이나 새로운 소켓이 들어오면 채널즈는 라우팅 테이블을 찾아 해당 연결에 대한 적절한 컨슈머를 찾고 그 인스턴스를 하나 만들어 처리한다. => 장고 뷰와는 다르게 컨슈며는 오랫동안 동작(long-running) 한다.
'웹 프로그래밍' 카테고리의 다른 글
Docker Error (file not found or excluded by .dockerignore) (0) | 2021.09.01 |
---|---|
HTTPS/SSL 적용 (Let's encrypt) (0) | 2021.08.31 |
AWS 요금정리 (0) | 2021.07.29 |
Django form에 대한 정리 (0) | 2021.07.25 |
Django Transaction (0) | 2021.07.20 |