django中如何實現websocket,真正通過websocket實現群聊功能


django中如何實現websocket

安裝

pip3 install channles==2.3
1 解釋器版本建議使用python3.6

2 channles模塊版本建議使用2.3

基本配置

配置文件中注冊app

配置文件中定義配置

對應應用下新建py文件並且在文件內部定義變量

完成上述配置以后,django就會既支持http又支持websocket

django,pycharm創建的django項目會自動幫你創建全局的templates文件夾,

也可以在每一個應用下創建templates模板文件夾
如果出現多個應用和全局都有模板文件夾的情況,會優先查找全局,如果全局沒有,會按照配置文件中注冊的app的順序從上往下依次進行查找每一個應用下的templates
每一個應用都可以有自己的urls.py,views.py和templates,static

配置完成以后同時支持http與websocket的原因(源碼解析)

class ProtocolTypeRouter:
    """
    Takes a mapping of protocol type names to other Application instances,
    and dispatches to the right one based on protocol name (or raises an error)
    """
    def __init__(self, application_mapping):
        self.application_mapping = application_mapping
        if "http" not in self.application_mapping:
            self.application_mapping["http"] = AsgiHandler

配置完成以后

routing.py

from channels.routing import ProtocolTypeRouter,URLRouter
from django.conf.urls import url
from app01 import consumers

application = ProtocolTypeRouter({
    'websocket':URLRouter([
        # websocket相關的路由
        url(r'^chat/',consumers.ChatConsumer)
    ])
})

consumers.py

from channels.generic.websocket import WebsocketConsumer


class ChatConsumer(WebsocketConsumer):
    def websocket_connect(self, message):
        """客戶端請求建立鏈接時 自動觸發"""
        pass


    def websocket_receive(self, message):
        """客戶端發送數據過來  自動觸發"""
        pass


    def websocket_disconnect(self, message):
        """客戶端斷開鏈接之后  自動觸發"""
        pass
"""
http協議
	index路徑		index視圖函數
	訪問:瀏覽器窗口直接輸入的地址的

websocket協議
	chat路徑		ChatConsumer視圖類
	訪問:new WebSocket對象訪問
"""

真正通過websocket實現群聊功能:

通過自己維護一個列表存儲鏈接對象的方式完成了簡易版本的群聊,其實還可以用channels提供的模塊,channel-layers

# 后端 三個方法
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer

consumer_object_list = []


class ChatConsumer(WebsocketConsumer):
    def websocket_connect(self, message):
        # 客戶端請求鏈接時 自動觸發
        print('請求鏈接')
        self.accept()
        # 建立鏈接 並且自動幫你維護每一個客戶端
        # 將鏈接在列表中存儲一份
        consumer_object_list.append(self)

    def websocket_receive(self, message):
        # 客戶端發送數據過來 自動觸發
        print(message)
        text = message.get('text')
        # # 給客戶端發送消息 單獨發送
        # self.send(text_data=text)

        # 給所有的鏈接對象發送數據
        for obj in consumer_object_list:
            obj.send(text_data=text)

    def websocket_disconnect(self, message):
        # 客戶端斷開鏈接之后 自動觸發
        print('斷開鏈接')
        # 客戶端斷開之后,應該將當前對象移除
        consumer_object_list.remove(self)
        raise StopConsumer()

# 前端四個方法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1>聊天室</h1>
<input type="text" id="txt">
<button onclick="sendMsg()">發送</button>

<h1>聊天記錄</h1>
<div class="record"></div>
<script>
    var ws = new WebSocket('ws://127.0.0.1:8000/chat/');
    // 1 握手環節驗證成功后自動觸發 onopen
    ws.onopen = function () {
        console.log('握手成功!')
    };
    // 2 給服務端發送消息 人為觸發 send
    function sendMsg() {
        ws.send($('#txt').val())
    }
    // 3 服務端一旦有了消息 自動觸發 onmessage
    ws.onmessage = function (args) {
        // 獲取發送的數據
        // 創建p標簽
        var pEle = $('<p>');
        pEle.text(args.data);
        $('.record').append(pEle)
    };
    // 4 斷開鏈接之后 自動觸發 onclose
    ws.onclose = function () {
        ws.close()
    }
</script>
</body>
</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM