Django で WebSocket を構成して使用するための究極のソリューション

django ASGI/Channels スタートアップと ASGI/daphne の違い 

Django ASGI/Channels は、リアルタイム アプリケーションの同時接続を処理する非同期サーバー ゲートウェイ インターフェイス (ASGI) プロトコルのサポートを提供する Django フレームワークの拡張機能です。ASGI は、非同期 Web サーバーおよびアプリケーションを構築するための仕様です。

以前のバージョンでは、Django は WSGI (Web Server Gateway Interface) プロトコルを使用していました。これは、要求と応答のサイクルのみを処理できる同期プロトコルです。これは、従来の Django では、ロング ポーリング、WebSocket、およびその他の同様のリアルタイム アプリケーションを処理する場合に優れたパフォーマンスとスケーラビリティを提供できないことを意味します。

従来の Django とは異なり、Django ASGI/チャネルを使用して、チャット アプリケーションや通知システムなどのリアルタイム機能を備えた非同期アプリケーションを構築できます。チャネルは、非同期タスクを処理するためのメッセージ キューを提供し、WebSocket やロング ポーリングなどのテクノロジと組み合わせて使用​​できます。

ASGI/daphne は、ASGI 仕様に準拠し、ASGI アプリケーションの同時接続を処理できる非同期 Web サーバーです。これは、Channels によって公式に推奨される実稼働グレードのサーバーであり、高性能で信頼性の高い接続管理を提供します。ASGI/daphne と Django ASGI/Channels を使用して、リアルタイム機能を備えた Django アプリケーションをデプロイできます。

要約すると、Django ASGI/Channels は、リアルタイム アプリケーションの同時接続を処理できるようにする Django の拡張機能です。ASGI/daphne は、ASGI 仕様に準拠した非同期 Web サーバーであり、ASGI アプリケーションの同時接続を処理するために使用されます。この 2 つを組み合わせて使用​​すると、高性能でリアルタイム対応の Django アプリケーションを構築できます。

ファイルの例え

ダフネ起動コマンド

daphne プロジェクト名.asgi:application

Python 自体は http プロトコルのみをサポートしているため、WebSocket を使用するにはサードパーティのライブラリをダウンロードする必要があります。

pip install -U チャネル

 これをsetting.pyで設定し、チャネルをINSTALLED_APPに追加する必要があります。

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    ...
    'channels',
)
 

尾行添加

ASGI_APPLICATION = 'bug_プロジェクト名.asgi.application'

asgi.pyファイルを変更する


Channels.routing からosをインポート
django.core.asgi から ProtocolTypeRouter、URLRouter をインポート get_asgi_application
からインポートします。インポート ルーティング
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bug_Project2.settings')
#application = get_asgi_application()
application = ProtocolTypeRouter({    "http":get_asgi_application(),    "websocket":URLRouter(routing.websoctet_urlpatterns ) })


settings.pyと同じディレクトリにrouting.pyを作成します。 

django.urls から
Web インポート コンシューマーからre_path をインポート

websoctet_urlpatterns = [
    re_path('ws/(?P<group>\w+)/$',consumers.ChatConsumer.as_asgi()),
]

web.viewsにconsumer.pyを作成する 

# -*- コーディング:UTF-8 -*-

# 著者:管理者
# 連絡先: [email protected]
# 日時:2022/1/10 11:55
# ソフトウェア: PyCharm

"""
ファイルの説明:
"""

Channels.generic.websocket から WebsocketConsumer をインポート
Channels.Exceptions から StopConsumer をインポート

クラス ChatConsumer(WebsocketConsumer):

    def websocket_connect(self, message):
        # クライアントが WebSocket 接続リクエストをバックエンドに送信すると自動的にトリガーされます
        # バックエンドはクライアントが接続を作成できるようにします
        print('Someone is coming')
        self.accept()
        # クライアントに送信します時間
        self.send("ようこそ")

    def websocket_receive(self, message):
        # ブラウザは WebSocket に基づいてデータをバックエンドに送信し、メッセージ受け入れを自動的にトリガーします text
        = message['text']
        print("メッセージを受信しました-->", text)
        res = "{}SB ".format(text)
        if text == "Close":
            # クライアントはコマンドを送信して積極的に切断します
            self.close()
            print('Close by command')
            raise StopConsumer # サーバーが切断する場合は、StopConsumer 例外を実行します その後、websocket_disconnect は
        self.send(res)を実行しません
        # self.close() #バックエンドが WebSocket を積極的に切断します


    def websocket_disconnect(self, message):
        # クライアントはサーバーから切断し、自動的に
        print("Clientdetachs")をトリガーします
        raise StopConsumer

ジャンゴについて知っておくべきこと

  • wsgi、httpリクエストのみをサポートします
  • asgi、wsgi+非同期+websockt

settings.pyのinstalled_appsの最初の行

フロントエンド ページを使用して WebSocket をテストするだけです

<html lang="ja">
<head>
 <meta charset="UTF-16">
 <title>title</title>
 <style>
     .message{          height: 300px;          ボーダー: 1px ソリッド #dddddd;          幅: 100%;      }  </style> </head> </html> <div class="message" id="message"></div> <div>  <input type="text" placeholder="请输入" id="txt ">  <input type="button" value="送信" οnclick="sendMessage()"> </div>











<script>
 ソケット = new WebSocket("ws://127.0.0.1:8000/room/123/")
 //接続が作成された後にトリガーされます
 。socket.onopen = function (event) {      let tag = document.createElement(" div ");      tag.innerText = "[接続成功]";      document.getElementById("メッセージ").appendChild(tag);


 }


 //この関数は、WebSocket      がサーバーから情報を受け入れる      とき に自動的にトリガーされます      。").appendChild(タグ);  }



 function sendMessage(){      let tag = document.getElementById("txt");      ソケット.send(タグ.値);  }


 function closeConn() {      ソケット.close(); //サーバーは切断要求を送信します

 }
</script>

WebSocket の概要:

チャネル 4.0 以降、Daphne サーバーはデフォルトでは提供されません。

解決策は 2 つあります:
1. チャネルのバージョンを 3.x として指定します;
2. インストール時に pip3 install -U Channels["daphne"] を使用します。

現在の問題は、上位バージョンでも下位バージョンでも、必ず以下の問題が報告されることです。

その後、先生を見つけてコース内のソースコードを入手し、チュートリアルのコードを使用して実行しました。

この質問に戻りましょう

この罠で2日かかった

ValueError: スコープ タイプ「websocket」に対してアプリケーションが構成されていません

コース内のコードと作者のコードを比較し、何度もテストした結果、

これは websocket である必要があります。e 文字が欠けているのは、プロジェクトを作成するときに csdn リファレンス ソース コードをコピーしたネチズンが残した落とし穴であるはずです。

 次に、すべてのプロジェクトの依存関係を最新バージョンにアップグレードすると、スムーズに実行されるようになります。

 レンダリング

まとめ

Django に基づいて WebSocket リクエストを実装しますが、1 人に対してのみ処理できます

グループチャット (2)

チャネルに提供されるチャネル層に基づいて実装されます。

  • 設定で設定されています。

    CHANNEL_LAYERS = { 
        "デフォルト": { 
            "BACKEND": "channels.layers.InMemoryChannelLayer", 
        } 
    }
    pip3 インストールチャンネル-redis
    CHANNEL_LAYERS = { 
        "default": { 
            "BACKEND": "channels_redis.core.RedisChannelLayer", 
            "CONFIG": { 
                "hosts": [('10.211.55.25', 6379)] 
            }, 
        }, 
    }
  • コンシューマ内の特別なコード。

    from Channels.generic.websocket import WebsocketConsumer 
    from Channels.Exceptions import StopConsumer 
    from asgiref.sync import async_to_sync 
    class
    
    ChatConsumer(WebsocketConsumer): 
        def websocket_connect(self, message): #
            このクライアントから接続を受信
            self.accept() 
    #
            グループ番号を取得し、ルート内のグループを取得しますmatching 
            = self.scope['url_route']['kwargs'].get("group") 
    #
            クライアントの接続オブジェクトを特定の場所 (メモリまたは Redis) に追加します
            async_to_sync( self.channel_layer.group_add)(group, self.channel_name) 
    def
        websocket_receive(self, message): 
            group = self.scope['url_route']['kwargs'].get("group" 
    )
            # グループ内のすべてのクライアントに通知し、xx_oo メソッドを実行します。このメソッドでは任意の関数を定義できます。
            async_to_sync(self.channel_layer.group_send)(group, {"type": "xx.oo", 'message': message}) 
    def
        xx_oo(self, events): 
            text = events['message']['text' ] 
            self.send(text) 
    def
        websocket_disconnect(self, message): 
            group = self.scope['url_route']['kwargs'].get("group") 
    async_to_sync
            (self.channel_layer.group_discard)(group, self .channel_name) 
            raise StopConsumer( 
    )

要約する

ステーション b デモアドレス https://b23.tv/UZvBFy3

  • ウェブソケットとは何ですか? プロトコル。

  • Django に WebSocket と Channels コンポーネントを実装します。

    • 個別に接続してデータを送受信します。

    • リストとチャンネルレイヤーを手動で作成します。

[最も詳細な Django WebSocket の通信原理、チャット ルーム、ネットワーク全体の実践事例 - Bilibili] http:// https://b23.tv/os2enKj

参考リンクhttp://t.csdn.cn/RyrcC

代替リンクで WebSocket を構成するdjango_wsgi_qq_36606793 のブログに基づいて作成されたプロジェクトに WebSocket を実装する方法 - CSDN ブログ

おすすめ

転載: blog.csdn.net/qq_35622606/article/details/132542038