ASGI – Django Channels:實現 WebSocket 異步通信,打造高效的長連接系統

A. 簡介

ASGI,即非同步伺服器網關介面,是Channels和Daphne所依據的規範,旨在將Channels應用程式從特定的應用伺服器中解綁,提供一種撰寫應用程式和中介軟體代碼的共同方式。完整的ASGI規範可在https://asgi.readthedocs.io上找到。

B. Summary

ASGI 被結構化為一個單一的不同步可調用函數,該函數需要一個字典範圍(Scope)和兩個可調用函數,接收(receive)和發送(send):

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

範圍(Scope)字典定義了一個連接的屬性,例如它的遠程 IP(對於 HTTP)或用戶名(對於聊天協議),以及連接的生命週期。應用程式會針對每個範圍實例化一次——例如,每個 HTTP 請求或每個開啟的 WebSocket 連接都各自實例化一次。

範圍總是有一個 `type` 鍵,該鍵指示連接的類型以及在範圍中應該預期哪些其他鍵(以及預期的消息類型)。

`receive` 可等待對象提供發生的事件,這些事件以字典形式出現,而 `send` 可等待對象則以類似的字典格式將事件發送回客戶端。

協議伺服器位於客戶端和您的應用程式代碼之間,將原始協議解碼為範圍和事件字典,並將您發送回去的任何內容編碼回協議中。

C. Composability

ASGI 應用程序,如同 WSGI 一樣,設計為可組合的,其中包括 Channels 的路由和中介軟體組件,如 ProtocolTypeRouter 和 SessionMiddleware。這些只是 ASGI 應用程序,會將其他 ASGI 應用程序作為參數傳遞,因此您可以將整個 Django 專案作為一個頂級應用程序來處理,並根據您正在處理的連接類型,分配到正確的消費者。

D. Protocol Specifications

基本的 ASGI 規範僅描述了 ASGI 應用程式的介面,並未詳細說明網路協議如何編碼進入和抽取自 scopes 和事件字典。

HTTP & WebSocket協議規範:https://github.com/django/asgiref/blob/main/specs/www.rst

E. 總結

ASGI(非同步伺服器網關介面)是一個規範,旨在將Django Channels應用程式與特定的應用伺服器解綁,使得開發者可以撰寫獨立於伺服器的應用程式和中介軟體代碼。ASGI結構化為一個異步可調用函數,這個函數接收一個範圍(Scope)字典和兩個可調用函數:接收(receive)和發送(send)。範圍字典描述連接的屬性(如遠程IP或用戶名)及其生命週期。應用程式會為每個範圍(如HTTP請求或WebSocket連接)創建一個實例。`receive`函數用來接收事件訊息,`send`函數用來發送事件訊息。協議伺服器則在客戶端和應用程式間運作,負責處理連接和通信。