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中的json的基本使用方法
Dec 21 Python
使用实现pandas读取csv文件指定的前几行
Apr 20 Python
windows下numpy下载与安装图文教程
Apr 02 Python
python实现键盘输入的实操方法
Jul 16 Python
扩展Django admin的list_filter()可使用范围方法
Aug 21 Python
Python实现栈和队列的简单操作方法示例
Nov 29 Python
Python cookie的保存与读取、SSL讲解
Feb 17 Python
Python对象的属性访问过程详解
Mar 05 Python
python是怎么被发明的
Jun 15 Python
基于python实现删除指定文件类型
Jul 21 Python
Python实现生成bmp图像的方法
Jun 13 Python
Python多线程 Queue 模块常见用法
Jul 04 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
Thinkphp模板中截取字符串函数简介
2014/06/17 PHP
Symfony数据校验方法实例分析
2015/01/26 PHP
php从完整文件路径中分离文件目录和文件名的方法
2015/03/13 PHP
PHP设计模式之装饰器模式定义与用法详解
2018/04/02 PHP
PHP给前端返回一个JSON对象的实例讲解
2018/05/31 PHP
Yii2框架实现利用mpdf创建pdf文件功能示例
2019/02/08 PHP
Laravel框架源码解析之反射的使用详解
2020/05/14 PHP
用正则获取指定路径文件的名称
2007/02/27 Javascript
node.js中的fs.fchownSync方法使用说明
2014/12/16 Javascript
详解JavaScript UTC时间转换方法
2016/01/07 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
2016/10/10 Javascript
详解获取jq ul第一个li定位的四种解决方案
2016/11/23 Javascript
vue实现自定义日期组件功能的实例代码
2018/11/06 Javascript
微信公众号网页分享功能开发的示例代码
2020/05/27 Javascript
使用AutoJs实现微信抢红包的代码
2020/12/31 Javascript
[01:30:54]《加油DOTA》 第三期
2014/08/18 DOTA
将图片文件嵌入到wxpython代码中的实现方法
2014/08/11 Python
Python发送email的3种方法
2015/04/28 Python
Python中运算符&quot;==&quot;和&quot;is&quot;的详解
2016/10/08 Python
TensorFlow实现创建分类器
2018/02/06 Python
python中验证码连通域分割的方法详解
2018/06/04 Python
解决安装pyqt5之后无法打开spyder的问题
2019/12/13 Python
Python计算指定日期是今年的第几天(三种方法)
2020/03/26 Python
Python错误的处理方法
2020/06/23 Python
详解python UDP 编程
2020/08/24 Python
6种非常炫酷的CSS3按钮边框动画特效
2016/03/16 HTML / CSS
CSS3实现时间轴特效
2020/11/02 HTML / CSS
办公室助理岗位职责
2013/12/25 职场文书
班会关于环保演讲稿
2013/12/29 职场文书
人事部岗位职责范本
2014/03/05 职场文书
数学教育专业求职信
2014/07/22 职场文书
社区志愿者活动方案
2014/08/18 职场文书
城管执法人员纪律作风整顿思想汇报
2014/09/13 职场文书
研讨会通知
2015/04/27 职场文书
2015年物资管理工作总结
2015/05/20 职场文书
Python进度条的使用
2021/05/17 Python