運維平臺的一定少不了這樣的場景,即需要實時獲取後端數據,例如批量執行的結果,或者監控的狀態獲取,這個如果單靠瀏覽器頻繁的請求後端接口來更新數據,多少顯得有點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:
創建一個獨立的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>
一個簡單的聊天室就創建好了