目錄
文章
分類
標籤
AI ai android Bitbucket C# C++ Certbot ChatGPT Cloudflare Code Runner CPE CPU排程 cron Daphne Django DNS設定 Docker fused-location Git GPT HTML HTTPS kotlin Line Bot Linux location-app Mac macOS MySQL n8n Next.js Nginx OpenAI permissions Python Python Django Pytorch pytorch PyTorch rclone React Redis Replit SSL streamlit Swap Ubuntu Unity Vector VM設定 VSCode WebSocket WordPress Wordpress wordpress-備份 yolo 中位數 伺服器設定 修復 最佳住址 利率 前端 動態生成 即時通訊 卷積神經網路 場景切換 學習 安全性 專案管理 帳號建立 影像分類 後台 性能 惡意軟體 成績查詢 投資 排序 操作系統 效率 教學 殖利率 深度學習 演算法 版本控制 物件偵測 神經網絡 程式解題 程式設計 競程 系統管理 終端機 統計 網頁框架 股票 自動化 財務 資料共享 資料結構 距離計算 路由 遊戲開發 選單 部署 開發 開發技巧 開發環境 開發者 雲端備份 靜態文件
目錄
目錄
1090 字
5 分鐘
Django WebSocket 前後端即時通訊
全部步驟總結
-
安裝必要的套件:
Terminal window 1pip install channels channels_redis- channels:使 Django 支持 WebSocket。
- channels_redis:用來實現 Channel Layer,讓不同的 WebSocket 連接能夠進行通訊。
-
設定 Django 專案:
- 在
settings.py中添加 Channels 和 Channel Layer 配置:
1INSTALLED_APPS = [2# 其他已安裝的應用3'channels',4'chat', # 你的 WebSocket 應用5]67ASGI_APPLICATION = 'classify.asgi.application'89CHANNEL_LAYERS = {10'default': {11'BACKEND': 'channels_redis.core.RedisChannelLayer',12'CONFIG': {13"hosts": [('127.0.0.1', 6379)], # Redis 默認地址和端口14},15},16} - 在
-
創建
asgi.py文件: 在classify專案目錄下,確保asgi.py設定為:1import os2from django.core.asgi import get_asgi_application3from channels.routing import ProtocolTypeRouter, URLRouter4from channels.auth import AuthMiddlewareStack5from chat import routing67os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'classify.settings')89application = ProtocolTypeRouter({10"http": get_asgi_application(),11"websocket": AuthMiddlewareStack(12URLRouter(13routing.websocket_urlpatterns14)15),16}) -
創建
chat/routing.py文件: 設置 WebSocket 路由:1from django.urls import path2from . import consumers34websocket_urlpatterns = [5path('ws/chat/', consumers.ChatConsumer.as_asgi()),6] -
編寫
chat/consumers.py: 設計 WebSocket Consumer,可以通過 Channel Layer 發送消息:1import json2from channels.generic.websocket import AsyncWebsocketConsumer3from channels.layers import get_channel_layer4from asgiref.sync import async_to_sync56class ChatConsumer(AsyncWebsocketConsumer):7async def connect(self):8self.room_name = "chat_room"9self.room_group_name = f"chat_{self.room_name}"1011await self.channel_layer.group_add(12self.room_group_name,13self.channel_name14)15await self.accept()1617async def disconnect(self, close_code):18await self.channel_layer.group_discard(19self.room_group_name,20self.channel_name21)2223async def receive(self, text_data):24text_data_json = json.loads(text_data)25message = text_data_json['message']2627await self.channel_layer.group_send(28self.room_group_name,29{30'type': 'chat_message',31'message': message32}33)3435async def chat_message(self, event):36message = event['message']37await self.send(text_data=json.dumps({38'message': message39}))4041@staticmethod42def send_to_frontend(message):43channel_layer = get_channel_layer()44async_to_sync(channel_layer.group_send)(45"chat_chat_room",46{47'type': 'chat_message',48'message': message49}50) -
創建自定義 Django 命令: 在
chat/management/commands/send_message.py中添加:1from django.core.management.base import BaseCommand2from chat.consumers import ChatConsumer34class Command(BaseCommand):5help = 'Send a WebSocket message from backend'67def handle(self, *args, **kwargs):8message = "這是從後端通過 command 發送的 WebSocket 訊息"9ChatConsumer.send_to_frontend(message)10self.stdout.write(self.style.SUCCESS('Message sent successfully')) -
運行 Django 項目: 確保 Redis 在運行,然後啟動 Django:
Terminal window 1python3 manage.py runserver -
從命令行發送訊息: 使用自定義命令從後端發送訊息:
Terminal window 1python3 manage.py send_message
程式執行順序步驟
1. 用戶端建立 WebSocket 連接
當用戶開啟瀏覽器並連接到你的 WebSocket 路徑 /ws/chat/ 時,會觸發 ChatConsumer 的 connect() 方法:
- 步驟:
- 用戶端(例如瀏覽器)使用 JavaScript 建立 WebSocket 連接。
- Django Channels 會啟動
ChatConsumer的connect()方法。 - 用戶端被加入到
chat_chat_room群組,這是透過self.channel_layer.group_add()方法實現的。 - 連接成功後,
await self.accept()允許 WebSocket 連接繼續。
- Redis 的角色:
- Redis 會存儲群組
chat_chat_room的資訊,記錄有哪些 WebSocket 連接屬於這個群組。
- Redis 會存儲群組
2. 從後端發送訊息
當你運行以下命令時,將觸發後端發送訊息:
1python3 manage.py send_message- 步驟:
- Django 運行
send_message命令,調用ChatConsumer.send_to_frontend()方法。 send_to_frontend()使用get_channel_layer()取得 Channels Layer,並調用async_to_sync(channel_layer.group_send(...))發送訊息到chat_chat_room。- 這個訊息會被放入 Redis,由 Redis 處理接下來的訊息分發。
- Django 運行
3. 消費者接收訊息
每一個屬於 chat_chat_room 群組的 WebSocket 連接,都會收到這條訊息,並觸發 ChatConsumer 中的 chat_message() 方法:
- 步驟:
chat_message()方法會被觸發,接收來自 Redis 的訊息。- 它將訊息轉換為 JSON 格式,然後通過
await self.send(...)發送給 WebSocket 連接的用戶端。
4. 用戶端顯示訊息
前端的 JavaScript 監聽 onmessage 事件,並顯示從後端接收到的訊息:
- 步驟:
- 用戶端的 WebSocket 連接收到來自伺服器的訊息。
onmessage事件被觸發,並執行對應的 JavaScript 函數來處理這條訊息,例如在控制台打印出來或顯示在網頁上。
整體流程總結
- 建立連接:用戶端連接到
/ws/chat/,被加入到chat_chat_room群組,Redis 記錄連接資訊。 - 後端發送訊息:你運行
send_message命令,後端通過 Channels Layer 和 Redis 將訊息傳給chat_chat_room。 - 訊息分發:Redis 處理訊息分發,確保所有屬於
chat_chat_room的 WebSocket 連接都收到這條訊息。 - 前端接收並顯示:用戶端接收到訊息,觸發 JavaScript 的
onmessage事件,並在頁面上顯示內容。
Redis 的功能
- 作為 Channel Layer 的後端:Redis 被用來存儲和傳遞 WebSocket 訊息。當 Django 需要向某個群組或某個連接發送訊息時,Channels 會把訊息放入 Redis,然後由其他連接取出並傳遞給相應的 WebSocket。
- 訊息中繼:Redis 可以在多個 Django 節點之間中繼訊息,這使得即使在高負載或多伺服器環境下,WebSocket 仍然能穩定運作。
Channel Layer 的功能
- 實現群組通信:讓不同的 WebSocket 連接(甚至不同伺服器上的連接)可以被分組。通過
group_add()和group_send()來把訊息發送到特定的群組,使得多人可以即時收到更新。 - 跨進程通信:Channel Layer 可以在不同進程間傳遞訊息,允許伺服器間或與背景任務間的即時溝通。
部分資訊可能已經過時
目錄
文章
分類
標籤
AI ai android Bitbucket C# C++ Certbot ChatGPT Cloudflare Code Runner CPE CPU排程 cron Daphne Django DNS設定 Docker fused-location Git GPT HTML HTTPS kotlin Line Bot Linux location-app Mac macOS MySQL n8n Next.js Nginx OpenAI permissions Python Python Django Pytorch pytorch PyTorch rclone React Redis Replit SSL streamlit Swap Ubuntu Unity Vector VM設定 VSCode WebSocket WordPress Wordpress wordpress-備份 yolo 中位數 伺服器設定 修復 最佳住址 利率 前端 動態生成 即時通訊 卷積神經網路 場景切換 學習 安全性 專案管理 帳號建立 影像分類 後台 性能 惡意軟體 成績查詢 投資 排序 操作系統 效率 教學 殖利率 深度學習 演算法 版本控制 物件偵測 神經網絡 程式解題 程式設計 競程 系統管理 終端機 統計 網頁框架 股票 自動化 財務 資料共享 資料結構 距離計算 路由 遊戲開發 選單 部署 開發 開發技巧 開發環境 開發者 雲端備份 靜態文件
目錄