django默認只支持http協議html
若是你想讓django即支持http協議又支持websocket協議,則須要作如下配置前端
前提須要安裝channels:python
channles的安裝:web
""" 注意事項 1.不要安裝最新版本的channles,建議安裝2.3版本便可 2.python解釋器建議使用3.6 """ pip3 install channels==2.3
1.配置文件中註冊channels應用django
INSTALLED_APPS = [ # 1 註冊channles應用 'channels' ]
2.settings.py配置文件配置參數後端
# 2 配置啓動須要的參數 ASGI_APPLICATION = 'myapi.routing.application' # ASGI_APPLICATION = '項目名同名的文件夾名.內部的py文件名(默認就叫routing).routing文件內的變量名(默認就叫application)'
3.固定配置api
# 在項目名同名的文件夾下建立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) ]) })
**總結:**配置完成後django由原來默認的wsgiref替換成asgi啓動(asgi內部是基於達芙妮)瀏覽器
上述配置完成後 ,django就會同時支持http協議和websocket協議websocket
""" 原先基於http協議的路由與視圖函數對應關係仍是跟以前同樣urls.py、views.py 針對websocket協議的路由與視圖函數對應關係則須要在routing.py和consumers.py(在對應的應用下建立便可) """
# consumers.py from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer class ChatConsumer(WebsocketConsumer): def websocket_connect(self, message): """ 客戶端請求連接以後自動觸發 :param message: 消息數據 """ pass def websocket_receive(self, message): """ 客戶端瀏覽器發送消息來的時候自動觸發 :param message: 消息數據 """ pass def websocket_disconnect(self, message): """ 客戶端斷開連接以後自動觸發 :param message: """ pass
""" http協議 index >>> index函數 訪問:瀏覽器發送請求便可 websocket協議 chat >>> ChatConsumer類(3個方法) 訪問:藉助於new WebSocket對象 """
from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer consumer_object_list = [] class ChatConsumer(WebsocketConsumer): def websocket_connect(self, message): """ 客戶端請求連接以後自動觸發 :param message: 消息數據 """ # print('請求連接') self.accept() # 創建連接 # 連接成功以後就將當前連接對象往列表中存一份 consumer_object_list.append(self) def websocket_receive(self, message): """ 客戶端瀏覽器發送消息來的時候自動觸發 :param message: 消息數據 {'type': 'websocket.receive', 'text': '你好啊 美女'} """ # 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): """ 客戶端斷開連接以後自動觸發 :param message: """ # 客戶端斷開連接以後 應該將當前客戶端對象從列表中移除 consumer_object_list.remove(self) raise StopConsumer() # 主動報異常 無需作處理 內部自動捕獲
<h1>聊天室</h1> <div> <input type="text" id="text" placeholder="請輸入"> <input type="button" value="發送" onclick="sendMsg()"> <input type="button" value="斷開連接" onclick="close()"> </div> <h1>聊天紀錄</h1> <div id="content"> </div> <script> var ws = new WebSocket('ws://127.0.0.1:8000/chat/'); // 1 發送消息 ws.send() // 2 握手成功以後 自動觸發 ws.onopen // 3 服務端發送消息過來 自動觸發 ws.onmessage // 4 斷開連接 ws.close() // 0 握手成功以後自動觸發 ws.onopen = function () { alert('創建成功') }; // 1 給服務端發送消息 function sendMsg() { ws.send($('#text').val()); } // 2 接受服務端發送過來的消息 ws.onmessage = function (event) { // event是對象 var dataValue = event.data; // 獲取服務端的數據 // 用DOM操做將數據動態渲染到頁面上 var pEle = $('<p>'); pEle.text(dataValue); $('#content').append(pEle) }; // 3 斷開連接 function close() { ws.close() } </script>
總結app
""" 後端三個方法 websocket_connect websocket_receive websocket_disconnect 前端四個方法 // 1 發送消息 ws.send() // 2 握手成功以後 自動觸發 ws.onopen // 3 服務端發送消息過來 自動觸發 ws.onmessage // 4 斷開連接 ws.close() """
注意咱們上面的代碼實現的羣聊功能並非真正的合理,後續若是想要真正實現羣聊功能,官方提供了一個方法channel-layers模塊,