原文轉載自「劉悅的技術博客」https://v3u.cn/a_id_67
websocket是個啥?
webSocket是一種在單個TCP連接上進行全雙工通信的協議
webSocket使得客戶端和服務器之間的數據交換變得更加簡單,允許服務端主動向客戶端推送數據。在WebSocket API中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,並進行雙向數據傳輸
現在,很多網站爲了實現推送技術,所用的技術都是輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,然後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器需要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費很多的帶寬等資源。
而比較新的技術去做輪詢的效果是Comet。這種技術雖然可以雙向通信,但依然需要反覆發出請求。而且在Comet中,普遍採用的長鏈接,也會消耗服務器資源。
在這種情況下,HTML5定義了WebSocket協議,能更好的節省服務器資源和帶寬,並且能夠更實時地進行通訊
輪詢是幾個意思?
輪詢是最原始的實現實時Web應用的解決方案。輪詢技術要求客戶端以設定的時間間隔週期性地向服務端發送請求,頻繁地查詢是否有新的數據改動。明顯地,這種方法會導致過多不必要的請求,浪費流量和服務器資源。總之就是一種low到爆炸的原始作坊水平的技術。
本文通過基於dwebsocket庫來將socket嵌入到django服務中,使其服務兼具http協議和socket協議,能夠達到實時前後端通信,後端主動推送等功能
安裝dwebsocket庫
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple dwebsocket
定義視圖文件的邏輯views.py
#導入websocket裝飾器
from dwebsocket.decorators import accept_websocket
#接收前端信息
@accept_websocket
def test_socket(request):
if request.is_websocket():
for message in request.websocket:
c=str(message,encoding='utf-8')
print(c)
request.websocket.send(message)
#主動推送消息
@accept_websocket
def test_websocket(request):
if request.is_websocket():
while 1:
time.sleep(1) ## 向前端發送時間
dit = {
'time':time.strftime('%Y.%m.%d %H:%M:%S',time.localtime(time.time()))
}
request.websocket.send(json.dumps(dit))
路由配置urls.py
#websocket
path('socket_test',TemplateView.as_view(template_name='md_admin/socket.html')),
path('websocket_test',TemplateView.as_view(template_name='md_admin/socket_push.html')),
path('test_socket',test_socket),
path('test_websocket',test_websocket),
定義前端發送消息的頁面 socket.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Room</title>
</head>
<body>
<input id="chat-message-input" type="text" size="100"/><br/>
<input id="chat-message-submit" type="button" value="Send" onclick='sendmessage()'/>
</body>
<script>
//生成socket對象
var socket = new WebSocket("ws:" + window.location.host + "/md_admin/test_socket");
socket.onopen = function () {
console.log('WebSocket open');//成功連接上Websocket
};
socket.onmessage = function (e) {
console.log('message: ' + e.data);//打印服務端返回的數據
};
socket.onclose=function(e){
console.log(e);
socket.close(); //關閉TCP連接
};
if (socket.readyState == WebSocket.OPEN){
socket.onopen();
}
window.s = socket;
function sendmessage(){
window.s.send(document.getElementById("chat-message-input").value);
}
</script>
</html>
然後再定義一個頁面,測試後臺的主動推送socket_push.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Room</title>
</head>
<body>
</body>
<script>
//生成socket對象
var socket = new WebSocket("ws:" + window.location.host + "/md_admin/test_websocket");
socket.onopen = function () {
console.log('WebSocket open');//成功連接上Websocket
};
socket.onmessage = function (e) {
console.log('message: ' + e.data);//打印服務端返回的數據
};
socket.onclose=function(e){
console.log(e);
socket.close(); //關閉TCP連接
};
if (socket.readyState == WebSocket.OPEN){
socket.onopen();
}
</script>
</html>
可以看到,前後端無論是前端發送消息,還是後端主動推送消息,全部基於websocket,實現了真正意義上的實時通信,另外基於dwebsocket的聊天室可以在這裏下載源碼
https://gitee.com/QiHanXiBei/mei_do_mall/blob/master/dj_websocket.zip
原文轉載自「劉悅的技術博客」 https://v3u.cn/a_id_67