추가 의존 없이 Django 응용 프로그램에 WebSocket을 추가하는 방법
17334 단어 pythondjangoasgiwebsockets
현재 Django 3.0에는 ASGI의 기존 지원이 포함되어 있으며 Django 응용 프로그램에 WebSocket을 추가할 때 추가 의존 항목이 필요하지 않습니다.본 논문에서는 기본 ASGI 프로그램을 확장해서Django를 사용하여WebSocket을 처리하는 방법을 배울 것입니다.Websocket 연결, 전송, 수신 데이터를 어떻게 처리하고, 예시적인 ASGI 응용 프로그램에서 업무 논리를 실현하는지 토론할 것입니다.
개시하다
우선, 컴퓨터에 Python>=3.6을 설치해야 합니다.Django 3.0은
async
과 await
키워드를 사용했기 때문에 Python 3.6 및 더 높은 버전과 호환됩니다.파이썬 버전 설정이 완료되면 프로젝트 디렉터리를 만들고 cd
을 넣습니다.그런 다음 virtualenv에 Django를 설치하고 프로젝트 디렉토리에 새 Django 응용 프로그램을 만듭니다.$ mkdir django_websockets && cd django_websockets
$ python -m venv venv
$ source venv/bin/activate
$ pip install django
$ django-admin startproject websocket_app .
Django 애플리케이션의 websocket_app
디렉토리를 살펴보십시오.asgi.py
이라는 파일을 보실 수 있습니다.내용은 다음과 같습니다.import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'websocket_app.settings')
application = get_asgi_application()
이 파일은 기본 Django ASGI 설정을 제공하고 application
이라는 이름의 ASGI 애플리케이션을 공개하며 uvicorn
또는 daphne
같은 ASGI 서버를 사용하여 실행할 수 있습니다.추가 논의에 앞서 ASGI 애플리케이션이 어떻게 구성되는지 살펴보겠습니다.ASGI 응용 프로그램 구조
ASGI, 즉 비동기 서버 인터페이스 인터페이스는 파이톤을 사용하여 비동기 웹 서비스를 구축하는 규범이다.WSGI의 정신적 계승자로서 Django와 Flask 등 프레임워크가 WSGI를 오랫동안 사용해왔다.ASGI는 파이톤의 로컬
async
/await
기능을 사용하여 장기적인 연결을 지원하는 웹 서비스를 구축할 수 있습니다. 예를 들어 웹소켓과 서버에서 보내는 이벤트입니다.ASGI 응용 프로그램은
async
함수로 3개의 매개 변수를 받아들인다. scope
(현재 요청한 상하문), receive
(들어오는 이벤트를 감청할 수 있는 async
함수)와 send
(클라이언트에 이벤트를 보낼 수 있는 async
함수)이다.ASGI 응용 프로그램 내부에서는
scope
사전의 값 라우팅을 기반으로 요청할 수 있습니다.예를 들어 scope['type']
의 값을 검사해서 요청이 HTTP 요청인지 Websocket 요청인지 확인할 수 있습니다.클라이언트의 데이터를 감청하려면 await
함수 receive
을 사용할 수 있습니다.클라이언트에 데이터를 보낼 준비가 되었을 때 await
함수 send
을 사용하여 클라이언트에 보내고 싶은 모든 데이터를 전송할 수 있습니다.이것은 예시 프로그램에서 어떻게 작동하는지 보여 줍니다.ASGI 응용 프로그램 만들기
asgi.py
파일에서, Google은 Google ASGI 프로그램으로 Django의 기본 ASGI 프로그램 함수를 포장하여 Websocket 연결을 처리할 것입니다.이를 위해 우리는 async
이라는 application
함수를 정의해야 한다. 이것은 3개의 ASGI 매개 변수를 받아들인다. 그것이 바로 scope
, receive
과 send
이다.HTTP 요청을 처리해야 하기 때문에 get_asgi_application
호출 결과를 django_application
으로 변경합니다.application
함수에서 우리는 scope['type']
의 값을 검사하여 요청 유형을 확정할 것이다.요청 형식이 'http'
이면 요청은 일반적인 HTTP 요청입니다. Django가 처리해야 합니다.요청 유형이 'websocket'
이라면 논리를 스스로 처리해야 합니다.생성된 asgi.py
파일은 다음과 같습니다.import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'websocket_app.settings')
django_application = get_asgi_application()
async def application(scope, receive, send):
if scope['type'] == 'http':
# Let Django handle HTTP requests
await django_application(scope, receive, send)
elif scope['type'] == 'websocket':
# We'll handle Websocket connections here
pass
else:
raise NotImplementedError(f"Unknown scope type {scope['type']}")
웹 소켓 연결을 처리하기 위해 함수를 만들어야 합니다.websocket.py
파일이 있는 폴더에 asgi.py
이라는 파일을 만들고 3개의 ASGI 매개 변수를 수용하는 websocket_application
이라는 ASGI 응용 프로그램 함수를 정의합니다.다음에 우리는 websocket_application
파일에서 asgi.py
을 가져오고 application
함수에서 이를 호출하여Websocket 요청을 처리하고 scope
, receive
과 send
파라미터를 전달할 것이다.이렇게 해야 합니다.# asgi.py
import os
from django.core.asgi import get_asgi_application
from websocket_app.websocket import websocket_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'websocket_app.settings')
django_application = get_asgi_application()
async def application(scope, receive, send):
if scope['type'] == 'http':
await django_application(scope, receive, send)
elif scope['type'] == 'websocket':
await websocket_application(scope, receive, send)
else:
raise NotImplementedError(f"Unknown scope type {scope['type']}")
# websocket.py
async def websocket_applciation(scope, receive, send):
pass
다음은 웹 소켓 응용 프로그램의 논리를 실현합니다.클라이언트가 문자열 "ping"
을 보낼 때, 우리는 문자열 "pong!"
으로 응답할 것입니다.websocket_application
함수에서 연결이 닫힐 때까지 무한 순환을 정의합니다.이 순환에서, 우리는 서버가 클라이언트로부터 새로운 이벤트를 받기를 기다릴 것입니다.그리고 이벤트의 내용에 대해 행동을 취하고 응답을 클라이언트에게 보낼 것입니다.우선 연결을 처리합시다.새로운 Websocket 클라이언트가 서버에 연결되면
'websocket.connect'
이벤트를 받을 것입니다.이러한 연결을 허용하기 위해서, 우리는 'websocket.accept'
이벤트를 응답으로 보낼 것입니다.이렇게 하면 Websocket 핸드셰이크가 완료되고 클라이언트와 지속적인 연결이 이루어집니다.클라이언트가 서버와의 연결을 종료할 때, 우리는 인터럽트 이벤트를 처리해야 한다.이를 위해
'websocket.disconnect'
행사를 듣겠습니다.클라이언트가 연결을 끊을 때, 우리는 우리의 무한 순환을 깨뜨릴 것이다.마지막으로, 우리는 클라이언트로부터 요청을 처리해야 한다.이를 위해
'websocket.receive'
행사를 듣겠습니다.클라이언트로부터 'websocket.receive'
이벤트를 받으면 event['text']
의 값이 'ping'
인지 확인합니다.만약 그렇다면 'websocket.send'
이벤트를 보내겠습니다. text
값은 'pong!'
입니다.Websocket 로직을 설정한 후
websocket.py
파일은 다음과 같습니다.# websocket.py
async def websocket_applciation(scope, receive, send):
while True:
event = await receive()
if event['type'] == 'websocket.connect':
await send({
'type': 'websocket.accept'
})
if event['type'] == 'websocket.disconnect':
break
if event['type'] == 'websocket.receive':
if event['text'] == 'ping':
await send({
'type': 'websocket.send',
'text': 'pong!'
})
테스트
현재, 우리의ASGI 응용 프로그램은 Websocket 연결을 처리하는 것으로 설정되어 있으며, 우리는 이미 Websocket 서버 논리를 실현하였으니, 한번 테스트해 봅시다.현재 Django 개발 서버는
asgi.py
파일을 사용하지 않으므로 ./manage.py runserver
테스트 연결을 사용할 수 없습니다.대신 ASGI 서버(예: uvicorn
)를 사용하여 어플리케이션을 실행해야 합니다.설치를 시작하겠습니다.$ pip install uvicorn
uvicorn
을 설치한 후에는 다음 명령을 사용하여 ASGI 애플리케이션을 실행할 수 있습니다.$ uvicorn websocket_app.asgi:application
INFO: Started server process [25557]
INFO: Waiting for application startup.
INFO: ASGI 'lifespan' protocol appears unsupported.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
Websocket 연결을 테스트하려면 새 탭에서 브라우저의 개발 도구를 엽니다.콘솔에서 Websocket
이라는 새로운 ws
실례를 만들어 ws://localhost:8000/
을 가리킨다.그리고 onmessage
프로세서를 ws
에 연결하고 이 프로세서는 event.data
을 컨트롤러에 기록한다.마지막으로 서버로 메시지를 보내려면 ws.send('ping')
으로 전화하십시오.콘솔에 기록된 값 "pong!"
을 보실 수 있습니다.> ws = new WebSocket('ws://localhost:8000/')
WebSocket {url: "ws://localhost:8000/", readyState: 0, bufferedAmount: 0, onopen: null, onerror: null, …}
> ws.onmessage = event => console.log(event.data)
event => console.log(event.data)
> ws.send("ping")
undefined
pong!
축하합니다!이제 ASGI를 사용하여 Django 응용 프로그램에 Websocket 지원을 추가하는 방법을 알게 되었습니다.얘로 좋은 거 만들어.😎👋 여보세요, 제인입니다.나는 응용 프로그램을 구축하는 것을 좋아하고, 다른 사람에게 어떻게 응용 프로그램을 구축하는지 가르치는 것을 좋아한다.Django,React,GraphQL을 이용한 응용 프로그램 구축에 대한 더 많은 게시물은 Twitter으로 연락하거나 jaydenwindle.com으로 저의 시사통신을 구독하세요.
Reference
이 문제에 관하여(추가 의존 없이 Django 응용 프로그램에 WebSocket을 추가하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jaydenwindle/adding-websockets-to-your-django-app-with-no-extra-dependencies-2f6h텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)