Django 实现 Websocket 广播、点对点发送消息的代码


Posted in Python onJune 03, 2020

1.Django实现Websocket

使用Django来实现Websocket服务的方法很多在这里我们推荐技术最新的Channels库来实现

1.1.安装DjangoChannels

Channels安装如果你是Windows操作系统的话,那么必要条件就是Python3.7

pip install channels

1.2.配置DjangoChannels

1.创建项目ChannelsReady

django-admin startprobject ChannelsReady

2.在项目的settings.py同级目录中,新建文件routing.py

# routing.py
from channels.routing import ProtocolTypeRouter

application = ProtocolTypeRouter({
 # 暂时为空
})

3.在项目配置文件settings.py中写入

INSTALLED_APPS = [
 'channels'
]

ASGI_APPLICATION = "ChannelsReady.routing.application"

1.3.启动带有Channels提供的ASGIDjango项目

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:13
Django 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,这样就算启动完成了

1.4.创建Websocket服务

1.创建一个新的应用chats

python manage.py startapp chats

2.在settings.py中注册chats

INSTALLED_APPS = [
 'chats',
 'channels'
]

3.在chats应用中新建文件chatService.py

from channels.generic.websocket import WebsocketConsumer
# 这里除了 WebsocketConsumer 之外还有
# JsonWebsocketConsumer
# AsyncWebsocketConsumer
# AsyncJsonWebsocketConsumer
# WebsocketConsumer 与 JsonWebsocketConsumer 就是多了一个可以自动处理JSON的方法
# AsyncWebsocketConsumer 与 AsyncJsonWebsocketConsumer 也是多了一个JSON的方法
# AsyncWebsocketConsumer 与 WebsocketConsumer 才是重点
# 看名称似乎理解并不难 Async 无非就是异步带有 async / await
# 是的理解并没有错,但对与我们来说他们唯一不一样的地方,可能就是名字的长短了,用法是一模一样的
# 最夸张的是,基类是同一个,而且这个基类的方法也是Async异步的

class ChatService(WebsocketConsumer):
 # 当Websocket创建连接时
 def connect(self):
 pass
 
 # 当Websocket接收到消息时
 def receive(self, text_data=None, bytes_data=None):
 pass
 
 # 当Websocket发生断开连接时
 def disconnect(self, code):
 pass

1.5.为Websocket处理对象增加路由

1.在chats应用中,新建urls.py

from django.urls import path
from chats.chatService import ChatService
websocket_url = [
 path("ws/",ChatService)
]

2.回到项目routing.py文件中增加ASGIHTTP请求处理

from channels.routing import ProtocolTypeRouter,URLRouter
from chats.urls import websocket_url

application = ProtocolTypeRouter({
 "websocket":URLRouter(
 websocket_url
 )
})

总结:

  • 下载
  • 注册到setting.py里的app
  • 在setting.py同级的目录下注册channels使用的路由----->routing.py
  • 将routing.py注册到setting.py
  • 把urls.py的路由注册到routing.py里
  • 编写wsserver.py来处理websocket请求
<template>
 <div>
 <input type="text" v-model="message">
 <p><input type="button" @click="send" value="发送"></p>
 <p><input type="button" @click="close_socket" value="关闭"></p>
 </div>
</template>


<script>
export default {
 name:'websocket1',
 data() {
 return {
  message:'',
  testsocket:''
 }
 },
 methods:{
 send(){
  
 // send 发送信息
 // close 关闭连接

  this.testsocket.send(this.message)
  this.testsocket.onmessage = (res) => {
  console.log("WS的返回结果",res.data);  
  }

 },
 close_socket(){
  this.testsocket.close()
 }

 },
 mounted(){
 this.testsocket = new WebSocket("ws://127.0.0.1:8000/ws/") 


 // onopen 定义打开时的函数
 // onclose 定义关闭时的函数
 // onmessage 定义接收数据时候的函数
 // this.testsocket.onopen = function(){
 // console.log("开始连接socket")
 // },
 // this.testsocket.onclose = function(){
 // console.log("socket连接已经关闭")
 // }
 }
}
</script>

3.广播消息

3.1客户端保持不变,同时打开多个客户端

3.2服务端存储每个链接的对象

socket_list = []

class ChatService(WebsocketConsumer):
 # 当Websocket创建连接时
 def connect(self):
 self.accept()
 socket_list.append(self)


 # 当Websocket接收到消息时
 def receive(self, text_data=None, bytes_data=None):
 print(text_data) # 打印收到的数据
 for ws in socket_list: # 遍历所有的WebsocketConsumer对象
 ws.send(text_data) # 对每一个WebsocketConsumer对象发送数据

4.点对点消息

4.1客户端将用户名拼接到url,并在发送的消息里指明要发送的对象

<template>
 <div>
 <input type="text" v-model="message">
 <input type="text" v-model="user">

 <p><input type="button" @click="send" value="发送"></p>
 <p><input type="button" @click="close_socket" value="关闭"></p>
 </div>
</template>


<script>
export default {
 name:'websocket1',
 data() {
 return {
  message:'',
  testsocket:'',
  user:''
 }
 },
 methods:{
 send(){
  
 // send 发送信息
 // close 关闭连接
  var data1 = {"message":this.message,"to_user":this.user}
  
  this.testsocket.send(JSON.stringify(data1))
  this.testsocket.onmessage = (res) => {
  console.log("WS的返回结果",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的返回结果",res.data);  
  }
 	
 // onopen 定义打开时的函数
 // onclose 定义关闭时的函数
 // onmessage 定义接收数据时候的函数
 // this.testsocket.onopen = function(){
 // console.log("开始连接socket")
 // },
 // this.testsocket.onclose = function(){
 // console.log("socket连接已经关闭")
 // }
 }
}
</script>

4.2服务端存储用户名以及websocketConsumer,然后给对应的用户发送信息

from channels.generic.websocket import WebsocketConsumer
user_dict ={}
list = []
import json
class ChatService(WebsocketConsumer):
 # 当Websocket创建连接时
 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)


 # 当Websocket接收到消息时
 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)


 # 当Websocket发生断开连接时
 def disconnect(self, code):
 pass

总结

到此这篇关于Django 实现 Websocket 广播、点对点发送消息的文章就介绍到这了,更多相关Django 实现 Websocket 广播、点对点发送消息内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python中快速进行多个字符替换的方法小结
Dec 15 Python
Python实现在线暴力破解邮箱账号密码功能示例【测试可用】
Sep 06 Python
理论讲解python多进程并发编程
Feb 09 Python
Python对象中__del__方法起作用的条件详解
Nov 01 Python
啥是佩奇?使用Python自动绘画小猪佩奇的代码实例
Feb 20 Python
python 图片去噪的方法示例
Jul 09 Python
Python 使用 Pillow 模块给图片添加文字水印的方法
Aug 30 Python
Python print不能立即打印的解决方式
Feb 19 Python
python sitk.show()与imageJ结合使用常见的问题
Apr 20 Python
解决pycharm中的run和debug失效无法点击运行
Jun 09 Python
基于tf.shape(tensor)和tensor.shape()的区别说明
Jun 30 Python
python解包概念及实例
Feb 17 Python
使用python实现时间序列白噪声检验方式
Jun 03 #Python
部署Django到阿里云服务器教程示例
Jun 03 #Python
Python flask路由间传递变量实例详解
Jun 03 #Python
django的autoreload机制实现
Jun 03 #Python
浅谈python量化 双均线策略(金叉死叉)
Jun 03 #Python
Django用户登录与注册系统的实现示例
Jun 03 #Python
python 瀑布线指标编写实例
Jun 03 #Python
You might like
超小PHP小马小结(方便查找后门的朋友)
2012/05/05 PHP
php项目中百度 UEditor 简单安装调试和调用
2015/07/15 PHP
PHP结合jquery ajax实现上传多张图片,并限制图片大小操作示例
2019/03/01 PHP
js异或加解密效果代码
2008/06/25 Javascript
javascript显示选择目录对话框的代码
2008/11/10 Javascript
javascript 精粹笔记
2010/05/09 Javascript
javascript五图轮播切换实用版
2012/08/17 Javascript
用JavaScript修改CSS属性的代码
2013/05/06 Javascript
不提示直接关闭网页窗口的JS示例代码
2013/12/17 Javascript
jquery使用经验小结
2015/05/20 Javascript
JS实现可关闭的对联广告效果代码
2015/09/14 Javascript
JavaScript中省略元素对数组长度的影响
2016/10/26 Javascript
手机移动端实现 jquery和HTML5 Canvas的幸运大奖盘特效
2016/12/06 Javascript
JavaScript组成、引入、输出、运算符基础知识讲解
2016/12/08 Javascript
canvas学习之API整理笔记(二)
2016/12/29 Javascript
jQuery实现select下拉框获取当前选中文本、值、索引
2017/05/08 jQuery
详解vue组件通信的三种方式
2017/06/30 Javascript
使用Node.js搭建静态资源服务详细教程
2017/08/02 Javascript
史上最全JavaScript常用的简写技巧(推荐)
2017/08/17 Javascript
Parcel.js + Vue 2.x 极速零配置打包体验教程
2017/12/24 Javascript
微信小程序实现选项卡效果
2018/11/06 Javascript
Vue的路由及路由钩子函数的实现
2019/07/02 Javascript
[05:08]第一届“网鱼杯”DOTA2比赛精彩集锦
2014/09/05 DOTA
Django中间件工作流程及写法实例代码
2018/02/06 Python
python爬取各类文档方法归类汇总
2018/03/22 Python
virtualenv 指定 python 解释器的版本方法
2018/10/25 Python
Python变量类型知识点总结
2019/02/18 Python
Python拆分大型CSV文件代码实例
2019/10/07 Python
Python实现七个基本算法的实例代码
2020/10/08 Python
CSS3感应鼠标的背景闪烁和图片缩放动画效果
2014/05/14 HTML / CSS
护理专科毕业推荐信
2013/11/10 职场文书
无子女夫妻离婚协议书(4篇)
2014/10/20 职场文书
校园环境卫生倡议书
2015/04/29 职场文书
七年级英语教学反思
2016/02/15 职场文书
Python实现随机生成迷宫并自动寻路
2021/06/13 Python
关于Oracle12C默认用户名system密码不正确的解决方案
2021/10/16 Oracle