기술문서 읽기

ASGI에 대해서

Mactto 2024. 2. 8. 10:09
728x90

ASGI의 공식문서를 번역한 글입니다.

공식문서 : https://asgi.readthedocs.io/en/latest/introduction.html


ASGI 소개

ASGI는 웹 서버, 프레임워크 및 애플리케이션 간의 호환성을 위한 오랜 Python 표준인 WSGI의 후속 버전입니다.

WSGI는 PYthon 웹 공간에서 훨씬 더 많은 자유와 혁신을 허용하는 데 성공했으며

ASGI의 목표는 이를 비동기식 Python 영역까지 확장하는 것입니다.


WSGI가 가지고 있던 문제점

WSGI를 왜 업그레이드 하려하는지 궁금할 수 있습니다.

문제는 일반적으로 WSGI의 단일 호출 가능 인터페이스가 WebSocket과 같은 웹 프로토콜에 적합하지 않다는 문제가 수 년에 걸쳐 제기되어 왔습니다.

 

WSGI 애플리케이션은 요청을 받고 응답을 반환하는 동작이 단일, 동기식으로 동작하기 때문에

long-poll HTTP 또는 WebSocket 연결과 같은 장기 커넥션을 허용하지 않습니다.

 

비록 내부 코드 동작을 비동기식으로 만들더라고 요청을 제공하는 경로는 여전히 하나뿐이므로

여러 개의 수신 이벤트가 있는 프로토콜은 이를 트리거할 수 없었습니다.


ASGI가 동작하는 방식

ASGI는 단일 비동기 식으로 동작합니다.

특정 연결에 대한 세부 정보가 포함된 dict인 범위, 보내기(애플리케이션이 클라이언트에 이벤트 메시지를 보낼 수 있게 하는 비동기 호출) 및 수신(애플리케이션이 클라이언트로부터 이벤트 메시지를 받을 수 있게 하는 비동기 호출) 을 사용합니다.

 

이는 각 애플리케이션에 대해 여러 개의 수신 이벤트와 발신 이벤트를 허용할 뿐만 아니라 애플리케이션이 다른 작업(예: Redis 대기열과 같은 외부 트리거에서 이벤트 수신대기)을 수행할 수 있도록 백그라운드 코루틴을 허용합니다.

 

다음은 애플리케이션에서 간단한 형태로 작성된 비동기 함수입니다.

async def application(scope, receive, send):
    event = await receive()
    ...
    await send({"type": "websocket.send", ...})

 

보내거나 받는 모든 이벤트는 미리 포맷이 정의된 Python dict입니다.

표준의 기초를 형성하고 서버 간에 애플리케이션을 교환할 수 있게 해주는 것이 바로 이러한 이벤트 형식입니다.

 

이러한 이벤트에는 각각 이벤트의 구조를 추론하는 데 사용할 수 있는 정의된 유형 키가 있습니다.

다음은 HTTP 요청의 본문과 함께 receive에서 수신할 수 있는 예제 이벤트입니다.

{
    "type": "http.request",
    "body": b"Hello World",
    "more_body": False,
}

 

그리고 아래는 Websocket 메시지를 보내기 위해 전달할 수 있는 이벤트의 예입니다.

{
    "type": "websocket.send",
    "text": "Hello world!",
}

WSGI와의 호환성

ASSGI는 또한 WSGI의 상위 집합으로 설계되었으며 둘 사이를 변환하는 정의된 방법이 있으므로

WSGI 응용 프로그램이 변환 wrapper (asgiref 라이브러리에 제공)를 통해 ASGI 서버 내에서 실행될 수 있습니다.

스레드 풀을 사용하면 비동기 이벤트 루프에서 벗어나 동기 WSGI 애플리케이션을 실행할 수 있습니다.

728x90