爲美多商城(Django2.0.4)添加基於websocket的實時通信,主動推送,聊天室及客服系統

原文轉載自「劉悅的技術博客」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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章