Django Channels - Introduction

Scope란 connection의 정보를 뜻한다. remote IP, username, lifetime of connection등의 정보를 가지고 있다. Application은 한번의 scope당 한번씩 instantiate된다. HTTP에서는 각 request마다, socket에서는 각 WebSocket connection마다이다.

Consumer

각각의 프로토콜은 각자 다른 event들이 발생하며 이 event들은 메소드로 표현된다. 개발자는 각각의 event들을 어떻게 처리할지 코드만 작성하면 Django의 Channel이 스케쥴링과 병렬적으로 실행시켜준다.


class LogConsumer(WebsocketConsumer):

    def connect(self, message):
        Log.objects.create(
            type="connected",
            client=self.scope["client"],
        )
Channel은 asynchronous event loop을 기반으로 돌아간다.  하지만 위처럼 코드를 작성하면 synchronous thread에서 실행이 된다. 따라서 위의 코드처럼 blocking operation도 문제없이 잘 작동한다.
class PingConsumer(AsyncConsumer):
    async def websocket_connect(self, message):
        await self.send({
            "type": "websocket.accept",
        })

    async def websocket_receive(self, message):
        await asyncio.sleep(1)
        await self.send({
            "type": "websocket.send",
            "text": "pong",
        })
위처럼 작성하면 asynchronous하게 작동한다.


Cross-Process Communication

Application내에서 통신하는 것은 각 application바다 존재하는 application instance를 통해서 하면 되지만, application끼리 통신하는 것은 이야기가 달라진다. 데이터베이스 polling을 통해서 할 수도 있지만 Channels는 channel layer라는 개념을 도입했다. 각각의 application instance는 unique channel name을 가지고 있으며, group에 join할 수 있다.

# In a consumer
self.channel_layer.send(
    "myproject.thumbnail_notifications",
    {
        "type": "thumbnail.generate",
        "id": 90902949,
    },
)
위의 코드처럼 다른 process에게 broadcasting해줄 수 있다.



댓글

이 블로그의 인기 게시물

[Django REST Framework] create() vs perform_create()

[Django 공식문서 번역] REST Framework - Viewset and Router

[PostgreSQL 공부하기] PostgreSQL Index는 B-Tree를 어떻게 사용할까?