292번째 줄:
292번째 줄:
레디스 서버를 이용한 실시간 채팅 구현.
레디스 서버를 이용한 실시간 채팅 구현.
−
꽤 오래된 버전인 5를 사용하는데, 아마도 이는.. 5에서 처음으로 consumer groups이 구현된 버전인데, 이걸로 구현했기 때문이 아닐까 싶다.
+
꽤 오래된 버전인 5를 사용하는데, 아마도 이는.. 5에서 처음으로 consumer groups이 구현된 버전인데, 이걸로 구현했기 때문이 아닐까 싶다.(최신버전에서도 될진.. 검증이 필요하다.)
===사전설정===
===사전설정===
{| class="wikitable"
{| class="wikitable"
301번째 줄:
301번째 줄:
| 서버 설치
| 서버 설치
|설치 후 딱히 옵션을 변경할 내용은 없다.
|설치 후 딱히 옵션을 변경할 내용은 없다.
+
어차피 로컬에서 모든 작동이 수행되기 때문에.
−
어차피 로컬에서 모든 작동이 수행되기 때문에.
+
네이티브로 설치하는 게 아니라 도커를 사용할 거라면 아래로 넘어가자.
|[http://id8436.iptime.org:8080/mediawiki/index.php/Radis Redis] 문서 참조.
|[http://id8436.iptime.org:8080/mediawiki/index.php/Radis Redis] 문서 참조.
|-
|-
−
|서버 테스트
+
|도커
−
|서버가 잘 설치되었는지 테스트.
+
|도커가 설치되어 있다면 아래 명령으로 바로 설치, 서비스가 시작된다.
−
서버 구동에 대한 메시지가 뜬다.
+
−
|redis-server
+
docker run -p 6379:6379 -d redis:5
+
|아래 문서를 통해 도커 설치를 참고하자.
+
http://id8436.iptime.org:8080/mediawiki/index.php/Docker
|-
|-
|연동 라이브러리 설치
|연동 라이브러리 설치
327번째 줄:
330번째 줄:
}
}
</syntaxhighlight>을 추가해준다.
</syntaxhighlight>을 추가해준다.
−
|-
+
|}
−
|기능 확인
+
==기존 컨슈머 변형==
−
|리눅스 기반의 OS에서 개발과 서비스를 하고 있다면 기능의 확인이 수월하겠지만... 윈도우 기반의 OS에서 개발이 진행된다면 쉽지 않다.
+
위에서 작성한 컨슈머는 중간 확인을 위한 동기식 함수인데, 비동기식으로 다시 쓰이면 성능이 좋아진다. 아래와 같이 변형하자.<syntaxhighlight lang="python">
−
우측과 같이 파이썬 쉘을 통해 서버의 실행을 점검해보자.
+
import json
−
|<syntaxhighlight lang="bash">
+
−
python3 manage.py shell
+
from channels.generic.websocket import AsyncWebsocketConsumer
−
>>> import channels.layers
+
−
>>> channel_layer = channels.layers.get_channel_layer()
+
−
>>> from asgiref.sync import async_to_sync
+
class ChatConsumer(AsyncWebsocketConsumer):
−
>>> async_to_sync(channel_layer.send)('test_channel', {'type': 'hello'})
+
async def connect(self):
−
>>> async_to_sync(channel_layer.receive)('test_channel')
+
self.room_name = self.scope["url_route"]["kwargs"]["room_name"]
−
{'type': 'hello'}
+
self.room_group_name = "chat_%s" % self.room_name
+
+
# Join room group
+
await self.channel_layer.group_add(self.room_group_name, self.channel_name)
+
+
await self.accept()
+
+
async def disconnect(self, close_code):
+
# Leave room group
+
await self.channel_layer.group_discard(self.room_group_name, self.channel_name)
+
+
# Receive message from WebSocket
+
async def receive(self, text_data):
+
text_data_json = json.loads(text_data)
+
message = text_data_json["message"]
+
+
# Send message to room group
+
await self.channel_layer.group_send(
+
self.room_group_name, {"type": "chat_message", "message": message}
+
)
+
+
# Receive message from room group
+
async def chat_message(self, event):
+
message = event["message"]
+
+
# Send message to WebSocket
+
await self.send(text_data=json.dumps({"message": message}))
</syntaxhighlight>
</syntaxhighlight>
−
|}
==모델작성==
==모델작성==
chat 앱의 models.py 작성<syntaxhighlight lang="python">
chat 앱의 models.py 작성<syntaxhighlight lang="python">