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使用cPickle模块序列化实例
Sep 25 Python
Python实现的多线程端口扫描工具分享
Jan 21 Python
Python实现简单HTML表格解析的方法
Jun 15 Python
解析Mac OS下部署Pyhton的Django框架项目的过程
May 03 Python
Python实现完整的事务操作示例
Jun 20 Python
Python实现字符串匹配算法代码示例
Dec 05 Python
python3中的md5加密实例
May 29 Python
Python中的Numpy矩阵操作
Aug 12 Python
selenium+python截图不成功的解决方法
Jan 30 Python
Python基础之列表常见操作经典实例详解
Feb 26 Python
Python爬虫实现vip电影下载的示例代码
Apr 20 Python
python爬虫分布式获取数据的实例方法
Nov 26 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 array 的加法操作代码
2010/07/24 PHP
apache中为php 设置虚拟目录
2014/12/17 PHP
php常用数组array函数实例总结【赋值,拆分,合并,计算,添加,删除,查询,判断,排序】
2016/12/07 PHP
php常用数组函数实例小结
2016/12/29 PHP
Laravel实现表单提交
2017/05/07 PHP
laravel框架实现为 Blade 模板引擎添加新文件扩展名操作示例
2020/01/25 PHP
PHP随机生成中文段落示例【测试网站内容时使用】
2020/04/26 PHP
新老版本juqery获取radio对象的方法
2010/03/01 Javascript
jquery获取当前点击对象的value方法
2014/02/28 Javascript
JS实现简单的右下角弹出提示窗口完整实例
2016/06/21 Javascript
Angularjs手动解析表达式($parse)
2016/10/12 Javascript
js获取时间函数及扩展函数的方法
2016/10/30 Javascript
Bootstrap的基本应用要点浅析
2016/12/19 Javascript
vue中使用v-model完成组件间的通信
2019/08/22 Javascript
JavaScript实现背景自动切换小案例
2019/09/27 Javascript
微信小程序实现点击按钮后修改颜色
2019/12/05 Javascript
JS中==、===你分清楚了吗
2020/03/04 Javascript
js、jquery实现列表模糊搜索功能过程解析
2020/03/27 jQuery
微信小程序调用后台service教程详解
2020/11/06 Javascript
基于Cesium绘制抛物弧线
2020/11/18 Javascript
python发送伪造的arp请求
2014/01/09 Python
使用Python判断质数(素数)的简单方法讲解
2016/05/05 Python
python 文件操作api(文件操作函数)
2016/08/28 Python
通过shell+python实现企业微信预警
2019/03/07 Python
利用Python+阿里云实现DDNS动态域名解析的方法
2019/04/01 Python
Python运行异常管理解决方案
2020/03/09 Python
美国小蜜蜂Burt’s Bees德国官网:天然唇部、皮肤和身体护理产品
2020/06/14 全球购物
Linux文件系统类型
2012/02/15 面试题
老师给学生的表扬信
2014/01/17 职场文书
《夜晚的实验》教学反思
2014/02/19 职场文书
财务科科长岗位职责
2014/03/10 职场文书
目标责任书范本
2014/04/16 职场文书
绿色环保演讲稿
2014/05/10 职场文书
国际商务专业求职信
2014/07/15 职场文书
MongoDB使用profile分析慢查询的步骤
2021/04/30 MongoDB
浅谈JS和Nodejs中的事件驱动
2021/05/05 NodeJs