Django Management Command에서 websockets 및 asyncio 사용하기
AJAX 폴링에서 WebSocket 기반 업데이트로
모든 프론트엔드 클라이언트가 AJAX 호출을 수행하는 대신 백그라운드에서 지속적으로 실행되는 백그라운드 Django 관리 명령을 필요로 하는 잠시 동안 다시 작성하려는 의도가 있었습니다. 매우 빠르게 확장할 수 없게 되는 동일한 처리가 1초마다 발생합니다.
아이디어는 중앙 집중식 처리로 인해 프런트 엔드 클라이언트가 새 데이터의 AJAX에 필요한 데이터베이스 업데이트가 발생할 때마다 WebSocket 메시지로 프런트 엔드 클라이언트에 알리는 것이었습니다.
저는 Python에서 websocket이나 asyncio 코딩을 많이 해본 적이 없었고, 매우 재미있었습니다. C++와 같은 언어로 이벤트 핸들과 메시지 큐를 직접 처리하는 대신 Python은 await/async, coroutine/Task/Futures를 사용하여 매우 강력한 비동기 처리를 제공합니다.
예
다음은 Django 관리 명령의 약간 수정된 버전입니다.
다음은 Django 관리 명령의 약간 수정된 버전입니다.
import logging
from optparse import make_option
from django.core.management.base import BaseCommand
import asyncio
import websockets
from.utils import configure_logging
from.models import Task
from.settings import (WEBSOCKET_BIND_PORT,
WEBSOCKET_BIND_ADDRESS)
clients = set()
async def notify_clients():
if clients: # asyncio.wait doesn't accept an empty list
await asyncio.wait([client.send('updated') for client in clients])
async def main_loop():
while True:
modified = Task.objects.sync()
if modified > 0:
await notify_clients()
await asyncio.sleep(0.5)
async def register(websocket):
clients.add(websocket)
logging.info(f'Registered new user: {websocket}')
await notify_clients()
async def unregister(websocket):
clients.remove(websocket)
logging.info(f'Unregistered user: {websocket}')
await notify_clients()
async def handle_client(websocket, path):
await register(websocket)
try:
async for message in websocket:
if message == 'success':
pass
else:
await websocket.send('updated')
finally:
await unregister(websocket)
class Command(BaseCommand):
""" Monitor tasks and notify websocket clients when they are updated """
help = __doc__
def handle(self, *args, **options):
configure_logging(**options)
start_server = websockets.serve(handle_client,
WEBSOCKET_BIND_ADDRESS,
WEBSOCKET_BIND_PORT)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_until_complete(main_loop())
asyncio.get_event_loop().run_forever()
프론트엔드에서는 '업데이트된' 메시지를 기다리고 AJAX 호출만 트리거합니다.
var ws = new WebSocket("ws{{ websocket_secure | yesno:'s,' }}://" + window.location.hostname + ":{{ websocket_port }}/");
ws.onmessage = function (event) {
var type = event.data;
if (type == 'updated') {
$.getJSON('/task-list', function(data) {
// Populate some stuff
});
}
};
Reference
이 문제에 관하여(Django Management Command에서 websockets 및 asyncio 사용하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tkanemoto/fun-with-websockets-and-asyncio-in-python-10mp텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)