Django实现websocket
Django实现websocket
- WebSocket功能
- 使用介绍
- 安装
- 配置
- WebSocket接口--消息接收者的实现
- scope
- 通道层 channel layer
- 部署
- Web客户端连接
- Mac客户端
WebSocket功能
WebSocket长连接一般用于实现实时功能,例如web端的消息通知、会话等场景。
使用 WebSocket 向 Django 项目添加实时功能,一般有两个选择:
-
使用 Django Channels,这是一个向 Django 添加 WebSocket 等功能的项目。 Django 完全支持这种方法。 但是,它需要切换到新的部署架构;
-
在 Django 项目旁边部署一个单独的 WebSocket 服务。
方法2的实现一般可以借助 django-sesame 去管理会话的鉴权,本文不做过多阐述,可以点击参考链接,下面组要介绍方法1中Channels
在Django中的使用。
关于Channels:
- 源码地址 https://github.com/django/channels
- 文档介绍 https://channels.readthedocs.io/en/latest/
使用介绍
安装
pip install -U 'channels[daphne]'
需要使用daphne,是为了后续部署用于启动ASGI1服务。当然,若是你有其他的部署方式你可以仅安装channels。
配置
安装完后,需要在INSTALLED_APPS
配置中添加:
INSTALLED_APPS = ("daphne","django.contrib.auth","django.contrib.contenttypes","django.contrib.sessions","django.contrib.sites",...
)ASGI_APPLICATION = "mysite.asgi.application"
注意:
ASGI_APPLICATION
配置后正常可通过python manage.py runserver
启动服务,低版本Django不行,Django 5.x 版本可行。
添加文件 myproject/asgi.py
from django.core.asgi import get_asgi_application
from django.urls import re_path# Initialize Django ASGI application early to ensure the AppRegistry
# is populated before importing code that may import ORM models.
django_asgi_app = get_asgi_application()from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidatorapplication = ProtocolTypeRouter({# 同时能支持原有http协议的接口"http": django_asgi_app,# 增加websocket协议的支持"websocket": AllowedHostsOriginValidator(AuthMiddlewareStack(# 接口路由URLRouter([re_path(r"^chat/(?P<room_name>\w+)/$", consumers.ChatConsumer.as_asgi()),]))),
})
WebSocket接口–消息接收者的实现
接口实现可以继承WebsocketConsumer
/ AsyncConsumer
/ AsyncConsumer
,此处介绍WebsocketConsumer,代码示例:
class ChatConsumer(WebsocketConsumer):def connect(self):# django框架会自动处理websocket链接带上的headers信息进行鉴权认证,初始化成用户对象self.user = self.scope['user']self.accept()self.send(text_data="[Welcome %s!]" % self.user.username)def receive(self, *, text_data):if text_data.startswith("/name"):username = text_data[5:].strip()self.send(text_data="[set your username to %s]" % username)else:self.send(text_data=username + ": " + text_data)def disconnect(self, message):pass
值的一提的是,Django框架和Channels结合很好,Auth体系完全兼容,Django http中的header这里也能识别成User用户。
scope
Consumer接受到client端发来的websocket请求后,会将请求信息初始化成scope
,请求相关信息可以从self.scope
中获取,例如:
scope["client"]
client来源ip和port, eg:['127.0.0.1', 6533]
scope["user"]
根据headers等信息初始化的User用户scope["path"]
请求接口path路径scope["query_string"]
连接上的query参数scope["headers"]
请求headersscope["url_route"]
请求path定义路由解析出的参数,eg:{"args": {}, "kwargs": {"pk": 1}}
以上的介绍算是基本实现了一个简单的websoket服务。
若是实现较为复杂的群聊、或者广播通知该如何实现?下面 channel layer
。
通道层 channel layer
安装pip install channels_redis
通道层是一种通信系统。 它允许多个消费者实例相互通信以及与 Django 的其他部分通信。
通道层提供以下抽象:
- 通道是一个可以发送消息的邮箱。 每个频道都有一个名称。 知道频道名称的任何人都可以向该频道发送消息。
- 组是一组相关的通道。 一个团体有一个名字。 任何拥有群组名称的人都可以通过名称向群组添加/删除频道,并向群组中的所有频道发送消息。 不可能枚举特定组中有哪些频道。
每个消费者实例都有一个自动生成的唯一通道名称,因此可以通过通道层进行通信。
需要在Django settings.py
文件中添加配置
# Channels
ASGI_APPLICATION = "mysite.asgi.application"
CHANNEL_LAYERS = {"default": {"BACKEND": "channels_redis.core.RedisChannelLayer","CONFIG": {"hosts": [("127.0.0.1", 6379)],},},
}
接口代码实现
# chat/consumers.py
import jsonfrom asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumerclass ChatConsumer(WebsocketConsumer):def connect(self):# 这里是将群名room_name定义在了path中,通过正则提取self.room_name = self.scope["url_route"]["kwargs"]["room_name"]self.room_group_name = f"chat_{self.room_name}"# Join room groupasync_to_sync(self.channel_layer.group_add)(self.room_group_name, self.channel_name)self.accept()def disconnect(self, close_code):# Leave room groupasync_to_sync(self.channel_layer.group_discard)(self.room_group_name, self.channel_name)# Receive message from WebSocketdef receive(self, text_data):text_data_json = json.loads(text_data)message = text_data_json["message"]# Send message to room groupasync_to_sync(self.channel_layer.group_send)(self.room_group_name, {"type": "chat.message", "message": message})# Receive message from room groupdef chat_message(self, event):message = event["message"]# Send message to WebSocketself.send(text_data=json.dumps({"message": message}))
部署
服务启动 daphne -b 0.0.0.0 -p 8000 myproject.asgi:application
其他参数可以查看 daphne文档 。
websocket协议nginx代理示例配置如下:
upstream channels-backend {server localhost:8000;
}
...
server {...location / {try_files $uri @proxy_to_app;}...location @proxy_to_app {proxy_pass http://channels-backend;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_redirect off;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Host $server_name;}...
}
Web客户端连接
前端JS可以通过 WebSocket 实现连接,注意浏览器兼容问题即可。
// Create WebSocket connection.
const socket = new WebSocket("ws://localhost:8000/chat/room/");// Connection opened
socket.addEventListener("open", function (event) {socket.send("Hello Server!");
});// Listen for messages
socket.addEventListener("message", function (event) {console.log("Message from server ", event.data);
});
Mac客户端
借助工具 websocat , 可通过 brew install websocat
安装。
websocat ws://localhost:8000/chat/room/
# 加header
websocat -H="Authorization: Token xxxx" ws://localhost:8000/chat/room/
需要注意的是,
-H=""
中间等号不能用空格替代,否则无法生效,希望作者在之后的版本中个可以兼容这个问题。
可以关注下Django框架中提供的WSGI和ASGI的区别; ↩︎
相关文章:
Django实现websocket
Django实现websocket WebSocket功能使用介绍安装配置WebSocket接口--消息接收者的实现scope通道层 channel layer部署Web客户端连接Mac客户端 WebSocket功能 WebSocket长连接一般用于实现实时功能,例如web端的消息通知、会话等场景。 使用 WebSocket 向 Django 项…...
先进制造aps专题九 中国aps行业分析
国外aps的问题是不给国内客户定制算法 国外aps的算法都很强大,考虑几百个约束条件,各种复杂的工序关系,还有副资源约束特殊规格约束,排程还优化,光c写的算法代码就几十万行甚至上百万行 国内aps的问题是实现不了复杂的…...

力扣hot100:23. 合并 K 个升序链表
23. 合并 K 个升序链表 这题非常容易想到归并排序的思路,俩升序序列合并,可以使用归并的方法。 不过这里显然是一个多路归并排序;包含多个子数组的归并算法,这可以让我们拓展归并算法的思路。 假设n是序列个数,ni是…...

Lightweight Robust Size Aware Cache Management——论文泛读
TOC 2022 Paper 论文阅读笔记整理 问题 现代键值存储、对象存储、互联网代理缓存和内容交付网络(CDN)通常管理不同大小的对象,例如,Blob、不同长度的视频文件、不同分辨率的图像和小文件。在这种工作负载中,大小感知…...

搜索自动补全-elasticsearch实现
1. elasticsearch准备 1.1 拼音分词器 github地址:https://github.com/infinilabs/analysis-pinyin/releases?page6 必须与elasticsearch的版本相同 第四步,重启es docker restart es1.2 定义索引库 PUT /app_info_article {"settings": …...

连接远程的kafka【linux】
# 连接远程的kafka【linux】 前言版权推荐连接远程的kafka【linux】一、开放防火墙端口二、本地测试是否能访问端口三、远程kafka配置四、开启远程kakfa五、本地测试能否连接远程六、SpringBoot测试连接 遇到的问题最后 前言 2024-5-14 18:45:48 以下内容源自《【linux】》 仅…...

简单的 Cython 示例
1, pyx文件 fibonacci.pyx def fibonacci_old(n):if n < 0:return 0elif n 1:return 1else:return fibonacci_old(n-1) fibonacci_old(n-2) 2,setup.py setup.py from setuptools import setup from Cython.Build import cythonizesetup(ext_mod…...
Laravel时间处理类Carbon
时间和日期处理是非常常见的任务。Carbon 是一个功能强大的 PHP 扩展包,它为我们提供了许多方便的方法来处理日期和时间。在 Laravel 中,你无需单独安装 Carbon,因为 Laravel 默认已经包含了它。如果你正在使用 Laravel,那么你已经…...
2024年5月软考架构题目回忆分享
十年架构两茫茫 ,Redis , UML 夜来幽梦忽还乡 , 大数据, Lambda 选择题 1.需求分析和架构设计面临这两个不同对象,一个是问题空间,一个是解空间 这是英文题,总共五个题目,只记得这么多 2. …...

香橙派 AIpro开发板初上手
一、香橙派 AIpro开箱 最近拿到了香橙派 AIpro(OrangePi AIpro),下面就是里面的板子和相关的配件。包含主板、散热组件、电源适配器、双C口电源线、32GB SD卡。我手上的这个是8G LPDDR4X运存的版本。 OrangePi AIpro开发板是一款由香橙派与华…...

如何使用DotNet-MetaData识别.NET恶意软件源码文件元数据
关于DotNet-MetaData DotNet-MetaData是一款针对.NET恶意软件的安全分析工具,该工具专为蓝队研究人员设计,可以帮助广大研究人员轻松识别.NET恶意软件二进制源代码文件中的元数据。 工具架构 当前版本的DotNet-MetaData主要由以下两个部分组成…...

LeetCode---栈与队列
232. 用栈实现队列 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty): 实现 MyQueue 类: void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并返回元素int pee…...

【教程】利用API接口添加本站同款【每日新闻早早报】-每天自动更新,不占用文章数量
本次分享的是给网站添加一个每日早报的文章,可以看到本站置顶上面还有一个日更的日报,这是利用ALAPI的接口完成的!利用接口有利也有弊,因为每次用户访问网站的时候就会增加一次API接口请求,导致文章的请求会因为请求量…...
僵尸进程,孤儿进程,守护进程
【一】僵尸进程 1.僵尸进程是指完成自己的任务之后,没有被父进程回收资源,占用系统资源,对计算机有害,应该避免 """ 所有的子进程在运行结束之后都会变成僵尸进程(死了没死透)还保留着pid和一些运行过程的中的记录便于主进程查看(短时间…...

Nuxt3 中使用 ESLint
# 快速安装 使用该命令安装的同时会给依赖、内置模块同时更新 npx nuxi module add eslint安装完毕后,nuxt.config.ts 文件 和 package.json 文件 会新增代码段: # nuxt.config.ts modules: ["nuxt/eslint" ] # package.json "devDep…...

【Jmeter】性能测试之压测脚本生成,也可以录制接口自动化测试场景
准备工作-10分中药录制HTTPS脚本,需配置证书 准备工作-10分中药 以https://www.baidu.com/这个地址为录制脚本的示例。 录制脚本前的准备工作当然是得先把Jmeter下载安装好、JDK环境配置好、打开Jmeter.bat,打开cmd,输入ipconfig,…...

Go 编程技巧:零拷贝字符串与切片转换的高效秘籍
前言 在深入探讨Go语言中字符串与切片类型转换的高效方法之前,让我们先思考一个关键问题:如何在不进行内存拷贝的情况下,实现这两种数据类型之间的无缝转换?本文将详细解析Go语言中字符串(字符类型)和切…...

音视频开发—FFmpeg 音频重采样详解
音频重采样(audio resampling)是指改变音频信号的采样率的过程。采样率(sample rate)是指每秒钟采集的音频样本数,通常以赫兹(Hz)或每秒样本数(samples per second)表示。…...
统计本地端口占用情况
要查看MongoDB是否正在备份,可以通过以下几种方法: 查看MongoDB的进程列表: 使用命令ps -ef | grep mongo,这将列出所有正在运行的MongoDB进程。在输出的列表中,你可以查看是否有与备份相关的进程或任务正在运行。 查…...
【MySQL精通之路】SQL优化(1)-查询优化(9)-外部联接优化
主博客: 【MySQL精通之路】SQL优化(1)-查询优化-CSDN博客 上一篇: 【MySQL精通之路】SQL优化(1)-查询优化(8)-嵌套联接优化-CSDN博客 下一篇: 【MySQL精通之路】SQL优化(1)-查询优化(10)-外部联接简化-CSDN博客 外部联接包括LEFT JOIN和…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...