Django channels 實現websocket實時通訊

運維平臺的一定少不了這樣的場景,即需要實時獲取後端數據,例如批量執行的結果,或者監控的狀態獲取,這個如果單靠瀏覽器頻繁的請求後端接口來更新數據,多少顯得有點low

所以對django如何支持websocket長連接進行簡單的學習,以便後面集成到項目中

安裝channels:

pip3 install channels

先將channels註冊到app中:

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'channels',
'app',
'websocket',
'django_celery_beat',
'django_celery_results',
]

在配置文件中指定ASIG路由地址,因爲django默認是wsgi協議,channels就是通過asig,異步網關協議實現了websocket

ASGI_APPLICATION = 'captain.routing.application'

然後啓動django:

image.png

創建一個獨立的app:

python manage.py startapp websocket

在項目目錄下創建asgi.py文件:

"""
ASGI entrypoint. Configures Django and then runs the application
defined in the ASGI_APPLICATION setting.
"""
import os
import django
from channels.routing import get_default_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'captain.settings')
django.setup()
application = get_default_application()

在項目目錄下創建路由文件:

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import websocket.routing
application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(
URLRouter(
websocket.routing.websocket_urlpatterns
)
),
})


在app下面創建路由文件,將path和處理webscoket請求的函數進行綁定:

from django.urls import path
from websocket.consumers import ChatConsumer
websocket_urlpatterns = [
path('ws/chat/', ChatConsumer),
]


在app下面創建視圖,處理請求函數:

from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
class ChatConsumer(WebsocketConsumer):
def websocket_connect(self, message):
"""
        客戶端發送請求進來,觸發此方法
        :param message:
        :return:
        """
self.accept()
def websocket_receive(self, message):
"""
        客戶端發送消息,觸發此方法,並返回數據
        :param message:
        :return:
        """
print(message)
msg = message['text']
self.send(msg)
def websocket_disconnect(self, message):
"""
        客戶端主動斷開鏈接,觸發此方法
        :param message:
        :return:
        """
# 服務端觸發異常 StopConsumer
raise StopConsumer

創建前端測試文件:

➜  ~ cat socket.html
<div>
    <div>
        <input type="text" id="txt">
        <input type="button" value="send" onclick="sendMsg();">
        <input type="button" value="close" onclick="closeConn();">
    </div>
    <h2>聊天記錄</h2>
    <div id="content">
    </div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
<script>
    var ws = new WebSocket("ws://127.0.0.1:8088/ws/chat/");
    ws.onopen = function(){
        // 客戶端驗證握手環節完成之後,自動執行該方法
        console.log("鏈接成功。。。")
    };
    ws.onmessage = function (event) {
        //  接受服務端發送的消息
        //  客戶端完成握手驗證之後 觸發該方法
        console.log(event.data);
        var tag = $("<div>");
        tag.text(event.data);
        $("#content").append(tag);
        console.log(1)
    };
    function sendMsg() {
        // ws.send():發送消息
      ws.send($("#txt").val());
    };
    function closeConn() {
        // ws.close():關閉Websocket鏈接
        console.log("斷開鏈接。。。");
        ws.close();
    };
</script>


一個簡單的聊天室就創建好了

image.png

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