記事ディレクトリ
Webソケットとソケット接続の違い
-
Websocket と Socket は 2 つの異なる通信プロトコルで、どちらもネットワーク接続を確立するために使用されますが、それぞれに独自の特性と適用可能なシナリオがあります。それらの主な違いは次のとおりです。
-
ウェブソケット
-
双方向通信: Websocket プロトコルはクライアントとサーバー間の双方向通信を実現でき、相手がオンラインであれば、いつでもクライアントとサーバーは積極的に通信を開始できます。
-
HTTP ベースのハンドシェイク: Websocket 接続を作成するには、HTTP プロトコルを介したハンドシェイクが必要です。このハンドシェイクが完了すると、その後のデータ転送は HTTP に依存せず、Websocket 接続経由で直接行われます。
-
データ送信のオーバーヘッドが少ない: 接続が確立された後のデータ フレームのヘッダーは 2 ~ 14 バイトであるため、各 HTTP 要求応答のヘッダーが少なくとも 500 ~ 800 バイトであるのに比べて、送信コストが大幅に削減されます。
-
全二重モード: 確立された接続では、クライアントとサーバーは同時にデータを送受信できます。
-
リアルタイム通信: Websocket は双方向の性質があるため、オンライン チャットや株式取引など、高頻度と低遅延を必要とするリアルタイムの対話シナリオに適しています。
-
-
ソケット
-
下位プロトコル: Socket は、TCP/IP または UDP をベースとした全二重通信を実現できる下位通信プロトコルです。
-
高い柔軟性: ソケットはネットワーク通信を制御する方法を提供し、ユーザーは特定の通信ニーズを満たすために必要に応じてプロトコルをカスタマイズできます。
-
複数の接続タイプ: ソケットは、TCP、UDP、RAW SOCKET などを含む複数の接続タイプをサポートします。
-
理解と使用が簡単: Websocket と比較して、Socket の原理と使用法は単純であり、ネットワーク プログラミングを学習するための基礎となります。
-
幅広い用途: ソケットは、FTP、POP3、TELNET などのさまざまなネットワーク サービスで広く使用されています。
-
一般に、Websocket と Socket にはどちらも独自の長所と短所があり、どのプロトコルを選択するかは特定のアプリケーション要件によって異なります。
Django との WebSocket 接続を確立する
ASGI vs WSGI
-
ASGI (Asynchronous Server Gateway Interface) および WSGI (Web Server Gateway Interface) は、Python Web サーバーの仕様です。主な違いは次のとおりです。
-
WSGI
-
同期処理: WSGI は同期インターフェイスであり、アプリケーションが一度に 1 つのリクエストを処理し、次のリクエストを処理する前に現在のリクエストを完了することを前提としています。
-
成熟していて安定しています: WSGI は Python で最も一般的に使用されている Web サーバー仕様であり、Flask や Django などの多数のライブラリやミドルウェアをサポートしています。
-
HTTP/1.0 の優れたサポート: WSGI を使用すると、HTTP/1.0 ベースの通信を簡単に行うことができます。
-
存続期間の長い接続と WebSocket のサポートが不十分: WSGI は同期であるため、長時間実行される接続や、複数のリクエスト (WebSocket や長時間ポーリングなど) の同時処理が必要なシナリオの処理には適していません。
-
-
ASGI
-
非同期処理: ASGI は、同時リクエストを処理できる非同期インターフェイスであり、アプリケーションのパフォーマンスを向上させます。
-
幅広いプロトコルのサポート: ASGI は HTTP をサポートするだけでなく、 WebSocketや HTTP/2 などの他のプロトコルも処理できます。
-
長時間接続と WebSocket の優れたサポート: ASGI は非同期 IO をサポートしているため、長時間接続、WebSocket 接続、および同時処理が必要なその他のシナリオの処理に非常に適しています。
-
新しいフレームワークの基礎を提供します。ASGI は、Starlette や FastAPI などのいくつかの新しい Python Web フレームワークで使用されます。
-
-
Websocket
したがって、現在のシナリオでは、に基づいて接続を構築したい場合は、ASGI ベースの構成方法を使用するのが自然です。 -
Django では、デフォルトでは WSGI アプリケーションを使用するため、ASGI アプリケーションを構成するには、次のファイル変更を行う必要があります。
ジャンゴ > 3.0
- Django バージョンのアップグレード: Django 3.0 から、Django は ASGI をサポートし始めました。Django のバージョンが 3.0 以上であることを確認してください。
チャンネル
- チャネルのインストール: Django では、ASGI をサポートするためにチャネル ライブラリが必要です。チャネルは pip 経由でインストールできます。
pip install channels
ダフネ
-
Daphne は、Django Channels プロジェクトによって開発された、HTTP、HTTP2、および WebSocket プロトコル用の ASGI (Asynchronous Server Gateway Interface) サーバーです。その主な役割は、クライアントからのリクエストを Django チャネルまたは他の ASGI アプリケーションに転送し、クライアントに応答を返すことです。
-
Daphne の主な機能は次のとおりです。
-
複数のプロトコルのサポート: Daphne は、HTTP/1.1、HTTP/2、およびリアルタイム通信を必要とする Web アプリケーションにとって非常に重要な WebSocket の 3 つのプロトコルをサポートします。
-
同時処理: イベントベースのサーバー モデルを使用することで、Daphne はサービスをブロックすることなく、多数の接続とリクエストを同時に処理できます。
-
Django チャネルとの互換性: Daphne は Django チャネルと完全な互換性があり、Django チャネル アプリケーションを直接実行できます。
-
拡張性: Django Channels にカスタム チャネル レイヤーを追加することで、Daphne がブロードキャスト メッセージやクロスプロセス通信などのより複雑な使用シナリオをサポートできるようになります。
-
-
全体として、Django Channels アプリを構築している場合、または Python アプリで ASGI を使用する必要がある場合は、Daphne が便利です。
pip install daphne
-
daphne
settings.py
また、次の部分でも設定する必要がありますINSTALLED_APPS
。
設定.py
- チャンネルを追加
INSTALLED_APPS
:settings.py
ファイル内で、チャンネルをINSTALLED_APPS
リストに追加します。INSTALLED_APPS = [ # ... 'channels', ]
- 設定
ASGI_APPLICATION
: settings.py ファイルにパスを設定しますASGI_APPLICATION
(settings.py
元のファイルにはそのようなものはありません。手動で追加する必要があります)。ASGI_APPLICATION = 'YOUR_PROJECT_NAME.routing.application'
Consumers.py と routing.py
-
プロジェクトのルート ディレクトリ (settings.py と同じディレクトリ) に routing.py ファイルを作成し、アクセス関数の関連ルーティングを定義します。ここで使用およびビルドする
websocket
必要があります。ProtocolTypeRouter
URLRouter
-
次に、接続リクエスト
views.py
を処理するビュー関数を定義したのと同じように、接続に関連するロジックを処理(新規作成)します。このコードは、実現したい内容に応じて、対応する関数を記述できます。socket
consumers.py
websocket
WebSocket接続をテストする
郵便屋さん
- まずは①で
websocket
接続方法を選択します - ②に自分のDjangoで定義したルートを入力します。
- クリックして
send
接続が成功したかどうかを確認します
Heroku が WebSocket アプリケーションをデプロイ
- 上記は、アプリケーションをローカルにデプロイするときに
websocket
完了する必要がある手順です . このパートでは、上記の変更に基づいてwebsocket
アプリケーションをHeroku に正常にデプロイする方法を説明します。
asgi.py
-
上記では、 を介して関連するルート
routing.py
を定義しましたが、websocket
デプロイ時にを使用せず、ファイルを介しrouting.py
てルートを定義することをお勧めしますasgi.py
。from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application from django.urls import path from nnsh_backend_new import consumers # Replace with your actual app name os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') application = ProtocolTypeRouter({ "http": get_asgi_application(), 'websocket': URLRouter([ path('ws/room/<str:room_name>/', consumers.RoomConsumer.as_asgi()), ]), })
-
ここに追加された
"http": get_asgi_application()
HTTP リクエストを Django の ASGI アプリケーションに委任することに注意してください。WebSocket リクエストは、定義したリクエストに渡されますURLRouter
。 -
要約すると、Django Channels プロジェクト用の asgi.py ファイルを作成することが非常に重要です。このファイルは、ASGI サーバーにさまざまな種類のリクエストの処理方法を指示します。これがないと、WebSocket ルーティングが正しく機能しない可能性があります。
- Django チャネルでは、
asgi.py
ルートをファイル内で直接定義するか、別のrouting.py
ファイルで定義してにasgi.py
インポートするかを選択できます。
WebSocket ルーティングが比較的単純な場合は、asgi.py
ファイル内で直接定義する方が便利な場合があります。ただし、複雑なルートやコンシューマが多数ある場合は、それらを別のrouting.py
ファイルに置くと、コードがより明確になり、管理しやすくなる可能性があります。
- ファイルをファイルに
asgi.py
インポートする方法を示す例を次に示します。routing.py
# asgi.py文件 import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter import YOUR_PROJECT_NAME.routing # 换成你的 app 名字 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'YOUR_PROJECT_NAME.settings') application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": URLRouter( yourapp.routing.websocket_urlpatterns ), })
- 次に、
YOUR_PROJECT_NAME.routing
WebSocket ルートを次のように定義します。# routing.py文件 from django.urls import re_path from . import consumers websocket_urlpatterns = [ re_path(r'ws/room/(?P<room_name>\w+)/$', consumers.RoomConsumer.as_asgi()), ]
routing.py
このプロジェクトでは、何も定義せずに、ルーティング関連のコンテンツをすべて に書き込むことasgi.py
にしました。
プロファイル
-
以前紹介しました
daphne
が、実際には使用しませんでした。これはデプロイするときにのみ必要であり、その機能はアプリケーションdaphne
を開くことです。asgi
-
前に
procfile
定義した書き込みメソッドは次のとおりです。web: gunicorn YOUR_PROJECT_NAME.wsgi
これは、次のようにしてアプリケーションgunicorn
を起動します。wsgi
-
ただし、アプリケーションは次の方法で開く
websocket
必要があります。daphne
-
そこで、Procfile を次の形式に変更します。
release: python manage.py makemigrations nnsh_backend_new && python manage.py migrate web: daphne -p $PORT -b 0.0.0.0 nnsh_backend_new.asgi:application
-
2 行目では、
$PORT
すべてのネットワーク インターフェイス上の Heroku によって割り当てられたポートで を介してリッスンするように Daphne に指示します。
-
この設定後、アプリケーションを再デプロイしたところ、アプリケーションが正常に動作すること
postman
がわかりました。websocket