카테고리 없음

TIL. 최종프로젝트(19) 웹소켓 기본구조

barryjung 2023. 6. 28. 21:33

[오늘 한일]

  • 웹소켓 상시연결 구성
  • 웹소켓 알림기능 작성

 

[오늘 배운점]

장고 channels

<웹소켓 기본구조>

오늘은 상시연결과 알림기능 구현을 위해 본격적으로 웹소켓을 작업했다.

웹소켓에 대해서는 다른 내용을 간단히 적었었는데,

기본 구조에 대해 정리해보겠다.

1. channels라이브러리 설치

먼저 장고에 channels와 daphne 라이브러리가 설치되야 한다.

daphne는 settings.py에 installed app에도 명시해준다.

 

2. asgi와 daphne활성화

asgi 설정을 하면 daphne를 asgi 웹서버로 삼아서 잘 동작하게 된다.

#settings.py
ASGI_APPLICATION = "config.asgi.application"
#asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidator

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")

application = ProtocolTypeRouter(
    {
        "http": get_asgi_application(),
        "websocket": AllowedHostsOriginValidator(
            AuthMiddlewareStack(URLRouter(battle.routing.websocket_urlpatterns))
        ),
    }
)

※ 여기서 나는 AuthmiddlewareStack을 저번에 만든 커스텀 미들웨어로 대체했던 것이다.

 

 

3. rounting.py, consumers.py 작성

asgi설정을 하면 asgi웹서버가 돌면서, 웹 요청을 처리하게 된다.

websocket 요청은 routing파일이 가진 urlpattern을 찾아가게 한다.

 

routing파일에서는 ws:// 메소드 요청의 url을 보고 어떤 컨슈머로 연결해줄지 라우팅한다.

#routing.py
from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r"ws/battle/", consumers.BattleConsumer.as_asgi()),
]

ws/battle은 순수히 url값이 되어 consumer를 지칭하는 역할을 한다.

 

4. 실질적인 웹소켓 처리는 consumers.py

consumers.py에 도달한 ws요청은 해당 consumer를 만나 웹소켓 통신을 이어나가게 된다.

웹소켓은 3대 동작으로 이뤄진다.

connect, disconnect, receive다.

 

#consumer.py
class BattleConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        await self.accept()
        
    async def receive(self, text_data=None, bytes_data=None):
        pass
        
    async def disconnect(self, code):
        pass

상속해오는 모듈과 메소드의 기본형은 위와 같다.

connect는 accept를 내포하면 된다.

나머지 둘은 pass로 아무것도 적지 않아도 해당 동작을 잘 처리한다.

그저 각 해당 단계에서 원하는 동작을 추가해주면 된다.

 

connect는 또한 channel layer를 생성하여 채널을 배정하는 동작을 포함한다.

기본의 경우 라우팅 경로값을 채널명으로 지정한다.

(specipic.~~하는 값이다.)

 

여기까지가 웹소켓 연결의 기본 구조이다.

아무 리스폰스가 없겠지만, 연결이 생성되는 건 확인해볼수 있다.