비동기방식으로 변경하기
왜 비동기로 바꾸는가?
사실, 기존의 동기방식은 비동기 방식에 비해, I/O가 끝날때 까지 계속 기다려야 하므로 비효율적이라는 단점이 존재한다.
하지만, 비동기로 작성하는 경우 I/O가 끝나지 않아도 즉시 결과값이 리턴된다.
따라서, I/O과 완료되면 완료된것에 따른 콜백함수가 호출되는 방식으로 진행된다. 때문에, 계속 다른일을 할 수 있어서 더 효율적이게 된다.
이제 동기 방식으로된 코드를 비동기 방식으로 바꾸어 보자.
여담으로, Django ORM은 동기방식으로 작동한다.
Channels의 문서를 보면 Django ORM이 동기방식으로 작동하기 때문에 이를 비동기로 바꿔주는 함수가 존재한다. 이는 다음에 설명할 때가 있으면 작성해보는걸로...
수정은 간단하다. chat/consumer.py 코드를 다음과 같이 수정만 해주면 된다.
#chat/consumer.py
from channels.generic.websocket import AsyncWebsocketConsumer
import json
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message
}
)
async def chat_message(self, event):
message = event['message']
await self.send(text_data=json.dumps({
'message': message
}))
비동기 방식으로 Consumer를 사용하는 경우 위의 코드처럼 AsyncWebsocketConsumer와 같이, 앞에 Async가 붙은 Consumer 클래스를 사용해주면 된다.
그리고 파이썬에서는 async 키워드를 이용해서 async로 함수가 동작한다는 사실을 알려준다.
기본적으로 asyncio로 파이썬 자체 지원을 해주는데, 아마 이것으로 구현한 듯 하다.
또한, await를 이용해서 async 함수를 호출하고 실제 결과값을 받아 올 수 있다.
(I/O가 완료된 경우에만 await에 있는 함수부분이 실행 됨)
'Django > Django Channels' 카테고리의 다른 글
Django Channels(Web Socket) - 채팅방스럽게 다듬기 (0) | 2023.01.16 |
---|---|
Django Channels(Web Socket) - 회원가입 기능 추가하기 (0) | 2023.01.16 |
Django Channels(Web Socket) - 채팅 유저이름 추가하기 (0) | 2023.01.16 |
Django Channels(Web Socket) - Channels 사용해보기 (0) | 2023.01.15 |
Django Channels(Web Socket) - 개발환경 설정 (0) | 2023.01.15 |