π λ°€ λ¦κ²κΉμ§ νκ³ μΉ μμΌ μ°κ²°μ΄ λμ§ μμ κΌ ν΄λ΄κ³ μΆμ λ§μμ μ λ μ μμ€κ³ νλ€κ° μμΉ¨μ μΌμ° κΉ¨μ λ€μ λμ ν΄λ³΄μλ€.
κ²°λ‘ μ νλ‘ νΈ μΉμμΌκ³Ό django μ μ°κ²°μ΄ μ λ§Ίμ΄μ‘λ€.μ€μκ° μ±ν μ μν΄μλ λΉλκΈ° ν΅μ μ ν΄μΌνλλ° django μμ κΈ°λ³Έμ μΌλ‘ wsgi λ₯Ό μ¬μ©μ€.
λλ asgi.pyλ₯Ό λ°κΎΈμ΄ μ£Όμλ€.import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack from chats.routing import websocket_urlpatterns os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Togeduck.settings") application = ProtocolTypeRouter({ 'http': get_asgi_application(), 'websocket': AuthMiddlewareStack( URLRouter( websocket_urlpatterns ) ) })
application λΆλΆμ μ¨μ£Όλ©΄ λλλ° ProtocolTypeRouter κ° http μμ²μΈμ§ websocket μμ²μΈμ§ νλ¨νμ¬ μ²λ¦¬λ°©μμ λλμ΄ μ€ κ²μ΄λ€.
httpλ μ°λ¦¬κ° μλ μμΌλ‘ μ²λ¦¬κ° λ κ²μ΄κ³
websocket μ λν μμ²μ AuthMiddlewareStack λΌλ κ²μ ν΅ν΄ μ²λ¦¬ λλλ° channels ν¨ν€μ§μμ μ 곡νλ κ²μΌλ‘ μΈμ , μΏ ν€ λ―Έλ€μ¨μ΄λ₯Ό ν¬ν¨μν¨ λ―Έλ€μ¨μ΄λΌκ³ 곡μ λ¬Έμμ μ νμλ€.
http requestλ μλ€μΆμ΄ urls.pyλ‘ μ°λ¦¬κ° μ°κ²°μμΌ μ£Όκ³ websocketμ λ°λ‘ μ§μ ν΄ μ£Όμ΄μΌ νλ€.
routings.pyλ₯Ό λ§λ€μ΄ μ€ ν# routings.py from django.urls import path from . import consumers websocket_urlpatterns = [ path('ws/socket-server/', consumers.ChatConsumer.as_asgi()), ]
# consumers.py import json from channels.generic.websocket import WebsocketConsumer, AsyncWebsocketConsumer class ChatConsumer(WebsocketConsumer): def connect(self): self.accept() self.send(text_data=json.dumps({ 'type':'connect hyeong', 'message':'plz suc' }))
λλ λΉλκΈ° μ²λ¦¬λ₯Ό μν΄ Async websocket consumerμ websocketconsumer λ₯Ό λ λ€ import νμ¬ ν μ€νΈ ν΄ λ³΄μλ€.
websocketconsumerλ₯Ό μ¬μ©νκ² λλ€λ©΄ λΉλκΈ° μ²λ¦¬ μμ΄ ν¨μλ₯Ό μμ±νλ©΄ λλ€.
websocketconsumerλ₯Ό μ¬μ©νλ©΄μ async λ‘ λΉλκΈ° ν¨μλ₯Ό μμ±νλ©΄ μμ κ°μ΄ νΈλμμ΄νΉ κ³Όμ μμ μ€ν¨νλ€.μλλ λΉλκΈ° μ²λ¦¬λ₯Ό μν ν¨μ
import json from channels.generic.websocket import WebsocketConsumer, AsyncWebsocketConsumer class ChatConsumer(AsyncWebsocketConsumer): async def connect(self): await self.accept() await self.send(text_data=json.dumps({ 'type':'connect hyeong', 'message':'plz suc' }))
μ±κ³΅!!
μ§μ§...γ γ γ μ΄μ λΆν° μ€λ μμΉ¨κΉμ§ λ°λμ μ΄μμ μ΄ κ°λ¨ν μ½λμ νλ€.. γ γ γ λ¬Όλ‘ settings.pyλ asgi λ₯Ό μ¬μ©νκ² λ€λ μ€μ μ½λκ° νμνκ³ μΉ μμΌμ μ΄ν΄, django μμμ λΉλκΈ° μ²λ¦¬λ₯Ό μν 곡λΆμ μκ°μ ν¬μνλ€κ³ ν΄λ λ무λλ djangoμμ restνκ² μΉμμΌμ ꡬνν μλ£κ° μμ΄ λͺ¨λ κ²μ μ΄ν΄νκ³ μ½λλ₯Ό μμ±ν μ λ°μ μμλ€...
μλ¬΄νΌ μ°κ²°μ λκ³ ... μ΄μ μμ..!
π channelsλ₯Ό μ λ€λ£¨κΈ° μν΄μλ scopeλ₯Ό μ μμμΌ νλλ° scopeλ connection μ 보λ₯Ό μλ―Ένλ€. μΌλ¨ νλ² λ³΄λκ² μ μΌ μ΄ν΄κ° μ λλ€.
{'asgi': {'version': '3.0'}, 'client': ['127.0.0.1', 59657], 'cookies': {}, 'headers': [(b'host', b'localhost:8000'), (b'connection', b'Upgrade'), (b'pragma', b'no-cache'), (b'cache-control', b'no-cache'), (b'user-agent', b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' b' (KHTML, like Gecko) Chrome/106.0.5249.207 Whale/3.17.145.18' b' Safari/537.36'), (b'upgrade', b'websocket'), (b'origin', b'http://127.0.0.1:5500'), (b'sec-websocket-version', b'13'), (b'accept-encoding', b'gzip, deflate, br'), (b'accept-language', b'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7'), (b'sec-websocket-key', b'jETbRyO/rOjVTyjXwkxIWw=='), (b'sec-websocket-extensions', b'permessage-deflate; client_max_window_bits')], 'path': '/ws/socket-server/', 'path_remaining': '', 'query_string': b'', 'raw_path': b'/ws/socket-server/', 'server': ['127.0.0.1', 8000], 'session': <django.utils.functional.LazyObject object at 0x00000194D571B370>, 'subprotocols': [], 'type': 'websocket', 'url_route': {'args': (), 'kwargs': {}}, 'user': <channels.auth.UserLazyObject object at 0x00000194D571B340>}
μμκ°μ΄ μ°κ²° μ 보, asgi μ 보 λ± λ€μνκ² κ°μ§κ³ μμΌλ©° url_route μ kwars λ₯Ό ν΅ν΄ νλΌλ―Έν° μ λ¬μ΄ κ°λ₯νλ€.
π μμΌμμ ν΅μ λ§ λΉλκΈ°λ‘ μ²λ¦¬ν΄ 보μμΌ μ무 μλ―Έ μλ€. μ±ν λ°©μ 보μ λ©μΈμ§κ° μ μ₯λλ DBλ λκΈ°μμΌλ‘ νλνλ μ²λ¦¬ν κ²μ΄κΈ° λλ¬Έμ΄λ€. νμ¬ κΈ°κ» μ½λλ₯Ό λΉλκΈ°λ‘ μ§λ λκΈ°λ‘ λμν μ μκΈ° λλ¬Έμ μ΄λ΄λλ database_sync_to_asyncλ₯Ό μ¬μ©ν΄ μ£Όλ©΄ λλ€.
django orm νλ κ²κ³Ό κ°μ΄ consumers.pyμμ μ¬μ©ν΄μ£Όλ©΄ λλ€ ν λ² λ³΄λ©΄ μ΄ν΄κ° λ κ²μ΄λ€.@database_sync_to_async def get_user_db(self, user_id): user = User.objects.filter(id=user_id) if user: return user[0] return None
μμ§ν μ²μμ λ§λ§νλλ° μ§κΈμ μμΌ μ°κ²°λ λμκ³ λμ λ°©μλ κ±°μ λ€ μμκ°μ νλ‘ νΈλ₯Ό ꡬμΆνκ³ νλνλ λ§λ€λ©΄ λ κ² κ°λ€. μ΄κ²λλ¬Έμ μ μ λͺ»μ€λλ° κ·Έλλ μ¬λ°λ€. νκ³ μΆμ κΈ°λ₯μ΄κ³ μ±ν κΈ°λ₯μ ꡬννκ³ λ€μμ κ²°μ κΈ°λ₯λ ꡬννλ €λ©΄ μΌμμ΄ λ¬λ €μΌνλ€.
μ€λ λ!