Django 實(shí)現(xiàn) Websocket 廣播、點(diǎn)對(duì)點(diǎn)發(fā)送消息的代碼
1.Django實(shí)現(xiàn)Websocket
使用Django來實(shí)現(xiàn)Websocket服務(wù)的方法很多在這里我們推薦技術(shù)最新的Channels庫(kù)來實(shí)現(xiàn)
1.1.安裝DjangoChannels
Channels安裝如果你是Windows操作系統(tǒng)的話,那么必要條件就是Python3.7
pip install channels
1.2.配置DjangoChannels
1.創(chuàng)建項(xiàng)目ChannelsReady
django-admin startprobject ChannelsReady
2.在項(xiàng)目的settings.py同級(jí)目錄中,新建文件routing.py
# routing.pyfrom channels.routing import ProtocolTypeRouterapplication = ProtocolTypeRouter({ # 暫時(shí)為空})
3.在項(xiàng)目配置文件settings.py中寫入
INSTALLED_APPS = [ ’channels’]ASGI_APPLICATION = 'ChannelsReady.routing.application'
1.3.啟動(dòng)帶有Channels提供的ASGI的Django項(xiàng)目
You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.Run ’python manage.py migrate’ to apply them.February 01, 2020 - 17:27:13Django version 3.0.2, using settings ’ChannelsReady.settings’Starting ASGI/Channels version 2.4.0 development server at http://0.0.0.0:8000/Quit the server with CTRL-BREAK.
很明顯可以看到ASGI/Channels,這樣就算啟動(dòng)完成了
1.4.創(chuàng)建Websocket服務(wù)
1.創(chuàng)建一個(gè)新的應(yīng)用chats
python manage.py startapp chats
2.在settings.py中注冊(cè)chats
INSTALLED_APPS = [ ’chats’, ’channels’]
3.在chats應(yīng)用中新建文件chatService.py
from channels.generic.websocket import WebsocketConsumer# 這里除了 WebsocketConsumer 之外還有# JsonWebsocketConsumer# AsyncWebsocketConsumer# AsyncJsonWebsocketConsumer# WebsocketConsumer 與 JsonWebsocketConsumer 就是多了一個(gè)可以自動(dòng)處理JSON的方法# AsyncWebsocketConsumer 與 AsyncJsonWebsocketConsumer 也是多了一個(gè)JSON的方法# AsyncWebsocketConsumer 與 WebsocketConsumer 才是重點(diǎn)# 看名稱似乎理解并不難 Async 無非就是異步帶有 async / await# 是的理解并沒有錯(cuò),但對(duì)與我們來說他們唯一不一樣的地方,可能就是名字的長(zhǎng)短了,用法是一模一樣的# 最夸張的是,基類是同一個(gè),而且這個(gè)基類的方法也是Async異步的class ChatService(WebsocketConsumer): # 當(dāng)Websocket創(chuàng)建連接時(shí) def connect(self): pass # 當(dāng)Websocket接收到消息時(shí) def receive(self, text_data=None, bytes_data=None): pass # 當(dāng)Websocket發(fā)生斷開連接時(shí) def disconnect(self, code): pass
1.5.為Websocket處理對(duì)象增加路由
1.在chats應(yīng)用中,新建urls.py
from django.urls import pathfrom chats.chatService import ChatServicewebsocket_url = [ path('ws/',ChatService)]
2.回到項(xiàng)目routing.py文件中增加ASGI非HTTP請(qǐng)求處理
from channels.routing import ProtocolTypeRouter,URLRouterfrom chats.urls import websocket_urlapplication = ProtocolTypeRouter({ 'websocket':URLRouter( websocket_url )})
總結(jié):
下載 注冊(cè)到setting.py里的app 在setting.py同級(jí)的目錄下注冊(cè)channels使用的路由----->routing.py 將routing.py注冊(cè)到setting.py 把urls.py的路由注冊(cè)到routing.py里 編寫wsserver.py來處理websocket請(qǐng)求<template> <div> <input type='text' v-model='message'> <p><input type='button' @click='send' value='發(fā)送'></p> <p><input type='button' @click='close_socket' value='關(guān)閉'></p> </div></template><script>export default { name:’websocket1’, data() { return { message:’’, testsocket:’’ } }, methods:{ send(){ // send 發(fā)送信息 // close 關(guān)閉連接 this.testsocket.send(this.message) this.testsocket.onmessage = (res) => { console.log('WS的返回結(jié)果',res.data); } }, close_socket(){ this.testsocket.close() } }, mounted(){ this.testsocket = new WebSocket('ws://127.0.0.1:8000/ws/') // onopen 定義打開時(shí)的函數(shù) // onclose 定義關(guān)閉時(shí)的函數(shù) // onmessage 定義接收數(shù)據(jù)時(shí)候的函數(shù) // this.testsocket.onopen = function(){ // console.log('開始連接socket') // }, // this.testsocket.onclose = function(){ // console.log('socket連接已經(jīng)關(guān)閉') // } }}</script>
3.廣播消息
3.1客戶端保持不變,同時(shí)打開多個(gè)客戶端
3.2服務(wù)端存儲(chǔ)每個(gè)鏈接的對(duì)象
socket_list = []class ChatService(WebsocketConsumer): # 當(dāng)Websocket創(chuàng)建連接時(shí) def connect(self): self.accept() socket_list.append(self) # 當(dāng)Websocket接收到消息時(shí) def receive(self, text_data=None, bytes_data=None): print(text_data) # 打印收到的數(shù)據(jù) for ws in socket_list: # 遍歷所有的WebsocketConsumer對(duì)象 ws.send(text_data) # 對(duì)每一個(gè)WebsocketConsumer對(duì)象發(fā)送數(shù)據(jù)
4.點(diǎn)對(duì)點(diǎn)消息
4.1客戶端將用戶名拼接到url,并在發(fā)送的消息里指明要發(fā)送的對(duì)象
<template> <div> <input type='text' v-model='message'> <input type='text' v-model='user'> <p><input type='button' @click='send' value='發(fā)送'></p> <p><input type='button' @click='close_socket' value='關(guān)閉'></p> </div></template><script>export default { name:’websocket1’, data() { return { message:’’, testsocket:’’, user:’’ } }, methods:{ send(){ // send 發(fā)送信息 // close 關(guān)閉連接 var data1 = {'message':this.message,'to_user':this.user} this.testsocket.send(JSON.stringify(data1)) this.testsocket.onmessage = (res) => { console.log('WS的返回結(jié)果',res.data); } }, close_socket(){ this.testsocket.close() }, generate_uuid: function() { var d = new Date().getTime(); if (window.performance && typeof window.performance.now === 'function') { d += performance.now(); //use high-precision timer if available } var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace( /[xy]/g, function(c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16); } ); return uuid; }, }, mounted(){ var username = this.generate_uuid(); console.log(username) this.testsocket = new WebSocket('ws://127.0.0.1:8000/ws/'+ username +'/') console.log(this.testsocket) this.testsocket.onmessage = (res) => { console.log('WS的返回結(jié)果',res.data); } // onopen 定義打開時(shí)的函數(shù) // onclose 定義關(guān)閉時(shí)的函數(shù) // onmessage 定義接收數(shù)據(jù)時(shí)候的函數(shù) // this.testsocket.onopen = function(){ // console.log('開始連接socket') // }, // this.testsocket.onclose = function(){ // console.log('socket連接已經(jīng)關(guān)閉') // } }}</script>
4.2服務(wù)端存儲(chǔ)用戶名以及websocketConsumer,然后給對(duì)應(yīng)的用戶發(fā)送信息
from channels.generic.websocket import WebsocketConsumeruser_dict ={}list = []import jsonclass ChatService(WebsocketConsumer): # 當(dāng)Websocket創(chuàng)建連接時(shí) def connect(self): self.accept() username = self.scope.get('url_route').get('kwargs').get('username') user_dict[username] =self print(user_dict) # list.append(self) # 當(dāng)Websocket接收到消息時(shí) def receive(self, text_data=None, bytes_data=None): data = json.loads(text_data) print(data) to_user = data.get('to_user') message = data.get('message') ws = user_dict.get(to_user) print(to_user) print(message) print(ws) ws.send(text_data) # 當(dāng)Websocket發(fā)生斷開連接時(shí) def disconnect(self, code): pass
總結(jié)
到此這篇關(guān)于Django 實(shí)現(xiàn) Websocket 廣播、點(diǎn)對(duì)點(diǎn)發(fā)送消息的文章就介紹到這了,更多相關(guān)Django 實(shí)現(xiàn) Websocket 廣播、點(diǎn)對(duì)點(diǎn)發(fā)送消息內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. HTML DOM setInterval和clearInterval方法案例詳解2. 詳解CSS偽元素的妙用單標(biāo)簽之美3. HTML <!DOCTYPE> 標(biāo)簽4. javascript xml xsl取值及數(shù)據(jù)修改第1/2頁(yè)5. html小技巧之td,div標(biāo)簽里內(nèi)容不換行6. 告別AJAX實(shí)現(xiàn)無刷新提交表單7. 詳解盒子端CSS動(dòng)畫性能提升8. CSS Hack大全-教你如何區(qū)分出IE6-IE10、FireFox、Chrome、Opera9. XML入門精解之結(jié)構(gòu)與語法10. msxml3.dll 錯(cuò)誤 800c0019 系統(tǒng)錯(cuò)誤:-2146697191解決方法
