- 文章信息 - Author: 李俊才 (jcLee95)
Visit me at CSDN: https://jclee95.blog.csdn.net
My WebSite:http://thispage.tech/
Email: 291148484@163.com.
Shenzhen China
Address of this article:https://blog.csdn.net/qq_28550263/article/details/139129624
HuaWei:https://bbs.huaweicloud.com/blogs/427830
【介紹】:本文介紹在Django中搭建Websocket服務器的最基本知識。
目 錄
- 1. 概述
- 2. 模塊的安裝和配置
- 3. asgi.py路由
- 4. 創建WebSocket消費者
- 5. 在前端使用WebSocket與服務器通信
- 創建WebSocket對象
- 連接建立事件
- 接收消息事件
- 發送消息
- 連接關閉事件
1. 概述
WebSocket是一種在單個TCP連接上進行全雙工通信的協議。它最初由HTML5規范提出,旨在解決傳統HTTP協議在實時通信方面的不足。與HTTP****不同,WebSocket在建立連接后可以保持長連接狀態,允許服務器主動向客戶端發送數據,而不需要客戶端發起請求。
WebSocket通信過程如下:
- 客戶端發起一個HTTP請求,請求頭中包含Upgrade: websocket,表示希望將連接升級為WebSocket連接。
- 服務器響應請求,返回狀態碼101 Switching Protocols,表示同意升級協議。
- 連接升級完成后,客戶端和服務器就可以通過這個連接進行全雙工通信。
- 在通信過程中,客戶端和服務器可以隨時向對方發送數據,不受請求-響應模式的限制。
- 當一方關閉連接時,WebSocket連接就會被終止。
WebSocket使用ws://
(非加密)和wss://
(加密)作為協議前綴,默認端口分別為80
和443
。
WebSocket特別適合需要實時交互、頻繁通信的應用場景,例如:
- 聊天應用:
用戶可以實時發送和接收消息,無需刷新頁面。
服務器可以將新消息實時推送給在線用戶。
支持一對一聊天、群聊等多種聊天模式。
- 實時協作工具:
多個用戶可以同時編輯同一文檔或畫板,所有變更實時同步。
用戶可以看到其他用戶的鼠標位置、選擇內容等實時狀態。
常見的實時協作工具有在線文檔、在線繪圖等。
- 在線游戲:
玩家之間可以實時交互,如移動、攻擊、聊天等。
服務器可以將游戲狀態實時同步給所有玩家。
支持多人在線對戰、合作等游戲模式。
- 實時數據更新:
股票行情、匯率、商品價格等實時數據可以通過WebSocket推送給客戶端。
天氣預報、新聞推送等實時信息也可以使用WebSocket及時送達。
客戶端無需定時輪詢,可以節省帶寬和服務器資源。
- 物聯網(IoT)應用:
設備可以通過WebSocket與服務器保持長連接,實時上報數據。
服務器可以實時向設備發送控制指令,如開關燈、調節溫度等。
WebSocket可以提供低延遲、高效的設備通信方式。
2. 模塊的安裝和配置 2.1 安裝channels庫pip install channels
Channels是一個基于Django的庫,用于處理WebSocket等協議。
2.2 配置ASGI應用在settings.py
中添加以下配置:
INSTALLED_APPS = [...'channels',
]ASGI_APPLICATION = 'myproject.asgi.application'
3. asgi.py路由
3.1 創建ASGI應用文件
ASGI(Asynchronous Server Gateway Interface)用于作為服務器網關接口,它是Django Channels的一部分,用于處理異步請求,包括WebSocket請求。
在項目根目錄下創建asgi.py
文件:
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_applicationfrom . import rontingsos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')application = ProtocolTypeRouter({# 這里處理http路由"http": get_asgi_application(),# 這里處理WebSocket路由# rontings.py的websocket_urlpatterns"websocket": URLRouter(rontings.websocket_urlpatterns),
})
3.2 配置WebSocket路由
在項目根目錄下創建routing.py
文件:
from django.urls import re_path
from my_app1 import consumerswebsocket_urlpatterns = [re_path(r'ws/?p<group>\wt/$', consumers.ChatConsumer.as_asgi()),
]
這里定義的 websocket_urlpatterns 就類似于實現 HTTP 服務器時定義的 urlpatterns ,是對應于WebSocket服務的路由規則。
正則表達式r'ws/?p<group>\wt/$'
用于匹配WebSocket的URL。它匹配以ws/
開頭,后面跟著一個捕獲組group
,最后以/
結尾的URL。捕獲組group
可以捕獲URL中的一部分,并將其作為參數傳遞給消費者類。
消費者類consumers.ChatConsumer
(下一個小節會介紹)是我們定義的處理WebSocket連接和消息的類。通過調用as_asgi()
方法,我們將消費者類轉換為ASGI應用,以便在路由中使用。
當一個WebSocket請求的URL匹配這個路由規則時,Django Channels會將請求交給consumers.ChatConsumer
消費者類處理。消費者類可以處理連接的建立、接收消息、發送消息以及連接的關閉等事件。
WebSocket中的消費者,就類似于HTTP服務的View
在應用my_app1
創建一個consumers.py
文件,定義WebSocket消費者:
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumerclass ChatConsumer(WebsocketConsumer):def websocket_connect(self):self.accept()self.send('消息')def websocket_receive(self, message):# 客戶端基于websocket向后端發送數據時,自動觸發接收消息print(message)self.send(text_data="收到消息: " + message)# self.close()def websocket_disconnect(self, message):# 客戶端與服務器斷開連接時,自動觸發print("斷開連接")raise StopConsumer()
5. 在前端使用WebSocket與服務器通信
創建WebSocket對象
在前端中,通過JavaScript WebSocket API與服務器建立WebSocket連接,需要先創建一個 WebSocket 對象:
const socket = new WebSocket('ws://localhost:8000/ws/chat/');
在上述示例中,ws://localhost:8000/ws/chat/
是服務器的WebSocket地址。ws://
表示使用WebSocket協議,localhost:8000
是服務器的主機和端口,/ws/chat/
是WebSocket的路徑。
需要注意的是,WebSocket地址必須以ws://
(非加密)或wss://
(加密)開頭,而不是http://
或https://
。并且需要再次強調,WebSocket 是一個獨立的基于 TCP 的協議,本身并不是HTTP。它僅僅是初次握手時使用HTTP,一旦協議升級完成就沒什么關系了。
連接建立事件
創建WebSocket對象后,當與服務器的連接成功建立時,會觸發onopen
事件。我們可以通過為socket.onopen
屬性指定一個函數來處理連接建立的邏輯:
socket.onopen = function(event) {console.log('WebSocket連接已建立');// 連接建立后的其他邏輯
};
接收消息事件
當服務器向客戶端發送消息時,會觸發onmessage
事件。我們可以通過為socket.onmessage
屬性指定一個函數來處理接收到的消息:
socket.onmessage = function(event) {console.log('收到服務器消息:', event.data);// 處理接收到的消息
};
在onmessage
事件處理函數中,我們可以通過event.data
獲取服務器發送的消息數據,并根據需要進行處理,如更新頁面內容、觸發特定操作等。
發送消息
要向服務器發送消息,可以使用WebSocket對象的send
方法:
function sendMessage(message) {socket.send(message);
}
在上述示例中,sendMessage
函數接受一個message
參數,表示要發送的消息內容。調用socket.send(message)
即可將消息發送給服務器。
服務器接收到客戶端發送的消息后,會在服務器端的相應消費者中觸發websocket_receive
方法進行處理。
連接關閉事件
當WebSocket連接被關閉時,會觸發onclose
事件。我們可以通過為socket.onclose
屬性指定一個函數來處理連接關閉的邏輯:
socket.onclose = function(event) {console.log('WebSocket連接已關閉');// 連接關閉后的其他邏輯
};
在onclose
事件處理函數中,我們可以執行一些清理操作,如更新連接狀態、重新連接等。