1. 서버에 Redis server 설치
https://blog.daonelab.com/post/33/1829/
난 로컬에 설치하지 않고 서버에 설치하여 직접연결한다.
2. channels_redis 설치
(.venv) C:\Work\Python project\ws.daonelab.com>pip install channels_redis
원래는 python 3.10.5 로 진행했는데 channels_redis에서 설치오류가 발생해서, python 3.7.4로 다시 Django, channels 설치 후 진행했다.
Django를 가동해보면 아래 메시지가 나오는데, channels_redis 버전을 downgrade하니까 되더라
Exception inside application: ERR unknown command 'BZPOPMIN'
(.venv) C:\Work\Python project\ws.daonelab.com>pip uninstall channels_redis
(.venv) C:\Work\Python project\ws.daonelab.com>pip install channels-redis==2.4.2
근데 이렇게 하면 has no attribute 'as_asgi' 에러 메시지가 또 나오는데 이건 channels 버전이 낮아서 발생하는 문제다.
channels는 channels-redis설치하면 같이 설치되는데 직접 uninstall 하고 버전을 지정하여 설치한다.
channels-redis 2.4.2 requires channels~=2.2, but you have channels 3.0.1 which is incompatible.
설치가 완료되면 위 경고가 나오는데 일단 무시했다.
(.venv) C:\Work\Python project\ws.daonelab.com>pip uninatall channels
(.venv) C:\Work\Python project\ws.daonelab.com>pip install channels==3.0.1
에러없이 작동하는 channels와 channels-rediis 버전을 찾는게 힘들었다.
(.venv) C:\Work\Python project\ws.daonelab.com>pip list
Package Version
------------------- -------
aioredis 1.3.1
asgiref 3.5.2
async-timeout 4.0.2
attrs 21.4.0
autobahn 22.6.1
Automat 20.2.0
cffi 1.15.1
channels 3.0.1
channels-redis 2.4.2
constantly 15.1.0
cryptography 37.0.4
daphne 3.0.2
Django 3.2.14
hiredis 2.0.0
hyperlink 21.0.0
idna 3.3
incremental 21.3.0
msgpack 0.6.2
pip 22.1.2
pyasn1 0.4.8
pyasn1-modules 0.2.8
pycparser 2.21
pyOpenSSL 22.0.0
pytz 2022.1
service-identity 21.1.0
setuptools 40.8.0
six 1.16.0
sqlparse 0.4.2
Twisted 22.4.0
twisted-iocpsupport 1.0.2
txaio 22.2.1
typing_extensions 4.3.0
zope.interface 5.4.0
설치버전
Redis server : 3.2.12
channels : 3.0.1
channels-redis : 2.4.2
위 내용은 삽질이다.
서버에 Redis server를 설치할때 repository를 최신으로 갱신하지 않고 redis를 설치해서
redis가 최신버전으로 설치되지 않아 발생한 문제로 최신 Reids server로 설치후,
channels-redis, channels 최신버전으로 설치하면 위에서 발생한 문제 없이 잘 작동하였다.
위 삽질의 기록은 남겨둔다.
결국 최종 설치 버전은
Redis server : 7.0.4
channels : 3.0.5
channels-redis : 3.4.1
(.venv) C:\Work\Python project\ws.daonelab.com>pip uninstall channels-redis
(.venv) C:\Work\Python project\ws.daonelab.com>pip install channels-redis
(.venv) C:\Work\Python project\ws.daonelab.com>pip uninstall channels
(.venv) C:\Work\Python project\ws.daonelab.com>pip install channels
(.venv) C:\Work\Python project\ws.daonelab.com>pip list
Package Version
------------------- -------
.
.
channels 3.0.5
channels-redis 3.4.1
.
.
3. ws/settings.py
# WSGI_APPLICATION = 'ws.wsgi.application'
ASGI_APPLICATION = "ws.asgi.application" # add
CHANNEL_LAYERS = {
"default" : {
"BACKEND" : "channels_redis.core.RedisChannelLayer",
"CONFIG" : {
"hosts" : [("redis://:password@domain.com:portno/0")],
}
}
}
multi chat을 위한 redis server와 연결 설정, 이번 내용에는 필요없고 다음 장에 필요하다.
4. ws/asgi.py
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application
import chat.routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ws.settings')
application = ProtocolTypeRouter({
"http" : get_asgi_application(),
"websocket" : AllowedHostsOriginValidator
(
AuthMiddlewareStack
(
URLRouter
(
chat.routing.websocket_urlpatterns
)
)
)
})
websocket으로 접근시 routing담당할 module지정
5. chat/routing.py
from django.urls import path, re_path
from chat.consumers import *
websocket_urlpatterns = [
#re_path(r"ws/chat/(?P<room_name>\w+)/$", ChatConsumer.as_asgi()),
path("ws/chat/<str:room_name>/", ChatConsumer.as_asgi()),
]
각 접근 경로별 처리할 class method지정 (channels버전이 낮으면 as_asgi property가 없다고 에러메시지 나온다.)
6. chat/consumers.py
import json
from channels.generic.websocket import WebsocketConsumer
class ChatConsumer(WebsocketConsumer):
def connect(self):
return super().connect()
def disconnect(self, code):
return super().disconnect(code)
def receive(self, text_data=None, bytes_data=None):
text_data_json = json.loads(text_data)
message = text_data_json["message"]
self.send(text_data = json.dumps({
"message" : message
}))
브로우저로 접속하여 chat room을 입력하고 메시지를 입력하면 echo되는 걸 확인할 수 있다.
하지만 아직은 broadcast는 되지 않는다. 즉 동일 chat room에 접속한 다른 브라우저로는 메시지가 전달되지 않는다.