[TIL_Carrotww] 64 - 22/12/02

μœ ν˜•μ„Β·2022λ…„ 12μ›” 2일
0

TIL

λͺ©λ‘ 보기
75/138
post-thumbnail

πŸ“Carrotww의 μ½”λ”© 기둝μž₯

🧲 django channels 도전기

πŸ” λ°€ λŠ¦κ²ŒκΉŒμ§€ ν•˜κ³  μ›Ή μ†ŒμΌ“ 연결이 λ˜μ§€ μ•Šμ•„ κΌ­ ν•΄λ‚΄κ³  싢은 λ§ˆμŒμ— μž λ„ 잘 μ•ˆμ˜€κ³  ν•˜λ‹€κ°€ 아침에 일찍 κΉ¨μ„œ λ‹€μ‹œ λ„μ „ν•΄λ³΄μ•˜λ‹€.
결둠은 ν”„λ‘ νŠΈ μ›Ήμ†ŒμΌ“κ³Ό 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

πŸ” 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 λ₯Ό 톡해 νŒŒλΌλ―Έν„° 전달이 κ°€λŠ₯ν•˜λ‹€.

🧲 channels database_sync_to_async

πŸ” μ†ŒμΌ“μ—μ„œ ν†΅μ‹ λ§Œ λΉ„λ™κΈ°λ‘œ μ²˜λ¦¬ν•΄ 보아야 아무 의미 μ—†λ‹€. μ±„νŒ…λ°©μ •λ³΄μ™€ 메세지가 μ €μž₯λ˜λŠ” 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

🧲 μž‘λ‹΄

μ†”μ§νžˆ μ²˜μŒμ— λ§‰λ§‰ν–ˆλŠ”λ° μ§€κΈˆμ€ μ†ŒμΌ“ 연결도 λ˜μ—ˆκ³  λ™μž‘ 방식도 거의 λ‹€ μ•Œμ•„κ°€μ„œ ν”„λ‘ νŠΈλ₯Ό κ΅¬μΆ•ν•˜κ³  ν•˜λ‚˜ν•˜λ‚˜ λ§Œλ“€λ©΄ 될 것 κ°™λ‹€. μ΄κ²ƒλ•Œλ¬Έμ— μž μ„ λͺ»μž€λŠ”데 κ·Έλž˜λ„ μž¬λ°Œλ‹€. ν•˜κ³ μ‹Άμ€ κΈ°λŠ₯이고 μ±„νŒ… κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κ³  λ‹€μŒμ— 결제 κΈ°λŠ₯도 κ΅¬ν˜„ν•˜λ €λ©΄ 쉼없이 λ‹¬λ €μ•Όν•œλ‹€.
였늘 끝!

profile
Carrot_hyeong

0개의 λŒ“κΈ€