要点は、Amazon-ec2 インスタンスでチャネルを使用して Django アプリを実行していて、websockets が接続に失敗していることです。
Websockets に関する私のコードのほとんどは、こちらの django-channels チュートリアルからのものです。
トラフィックは、アプリケーション ロード バランサーの背後にある保護された dns 名を介して送信されています。
私はかなり最小限の構成でこれを完全に Daphne (https と websocket トラフィックの両方を処理) で実行しています:
daphne -b <server_url> -p <port> test_app.asgi:application
また、 mozilla-django-oidcモジュールを使用して openID-connect で認証しています。ただし、websocket テストでは、認証は期待していません。問題が何らかの方法で websocket 認証に関連している場合は、指摘する価値があると思います。
開発中は、チャネル レイヤーとしてローカルの redis クラスターを実行しています。私の開発アプリ (すべて http:// と ws://) には、websocket への接続に問題はありません。チャット アプリは期待どおりに動作します。WebSocket に接続でき、
127.0.0.1:60779 - - [07/Apr/2021:12:06:05] "WSCONNECTING /ws/chat/lobby/"
ここに asgi.py のコードがあります
import chat.routing
asgi_app = get_asgi_application()
from channels.auth import AuthMiddlewareStack
application = ProtocolTypeRouter(
{
"http": asgi_app,
"websocket": AuthMiddlewareStack(
URLRouter(chat.routing.websocket_urlpatterns)
),
}
)
および chat/routing.py のコード
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()),
]
本番環境では、チャネル レイヤーとして Elasticache Redis クラスターを使用しています。これを django シェルでテストすると、接続/送信/受信できます。
しかし、プロダクション チャットでは、ルームに到達できないか、上記のWSCONNECTINGメッセージが表示されません。接続を WebSocket にアップグレードすることはありません。その後の次のログは
2021-04-07 16:15:15,279 WARNING Not Found: /ws/chat/lobby/
そのルートを websocket ではなく http として解決しようとしているように。
追加の読み取りを行った後、Daphneで実行されているホスト/ポートを次のように使用しようとしました
wss://<my host ip>:<port>/ws/chat/lobby
これにより、すぐに障害が発生することはありませんでしたが、最終的には接続されませんでした。
(index):46 Uncaught DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.
websocket url でホスト名として使用されている公開ホスト名と関係があるように感じます。すべてのインバウンド トラフィックが許可されます。これが当面の問題にどのように関係しているかはわかりません。
私はまだこれらすべてを回避する方法を学ぼうとしています。アドバイスをいただければ幸いです。
ありがとう!