django3 websockets

article/2025/10/16 0:39:17

一、概述

现在Django 3.0附带了对ASGI的支持,将Websockets添加到Django应用中不需要任何额外的依赖关系。 在本文中,您将学习如何通过扩展默认的ASGI应用程序来使用Django处理Websocket。 我们将介绍如何在示例ASGI应用程序中处理Websocket连接,发送和接收数据以及实现业务逻辑。

 

注意:Django 3.0不支持dwebsocket模块,启动时,会报错:

TypeError: WebSocketMiddleware() takes no arguments

因此,如果使用Django 3.0,必须使用channels

 

channels介绍

channels是以django插件的形式存在,它不仅能处理http请求,还提供对websocket、MQTT等长连接支持。不仅如此,channels在保留了原生django的同步和易用的特性上还带来了异步处理方式(channels2.X版本),并且将django自带的认证系统以及session集成到模块中,扩展性非常强。官方文档:https://channels.readthedocs.io/en/latest/index.html

 

安装以及安装需求

channels2.0最低django版本要求是1.11+,python3.5+

本文采用的是python 3.7.3,django 3.1

pip3 install channels

 

二、开始使用

环境说明

Django==3.1
channels==2.4.0
paramiko==2.7.2
uvicorn==0.11.8

 

新建项目:django3_websocket,应用名称:web

 看一下与settings.py同级目录。 您应该看到一个名为asgi.py的文件。 其内容如下所示:

import osfrom django.core.asgi import get_asgi_applicationos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django3_websocket.settings')application = get_asgi_application()

该文件提供了默认的Django ASGI设置,并公开了一个名为application的ASGI应用程序,可以使用uvicorn或daphne等ASGI服务器运行该应用程序。 在进一步介绍之前,让我们看一下ASGI应用程序的结构。

 

ASGI应用程序结构

ASGI或“异步服务器网关接口”是用于使用Python构建异步Web服务的规范。它是WSGI的精神继承者,WSGI已被Django和Flask等框架使用了很长时间。 ASGI使您可以使用Python的本机异步/等待功能来构建支持长期连接的Web服务,例如Websockets和Server Sent Events。

ASGI应用程序是一个异步函数,它带有3个参数:作用域(当前请求的上下文),接收(一个异步函数,可让您侦听传入的事件)和发送(一个异步函数,可将事件发送至客户端)。

在ASGI应用程序内部,您可以根据范围字典中的值路由请求。例如,您可以通过检查scope [‘type’]的值来检查该请求是HTTP请求还是Websocket请求。要侦听来自客户端的数据,您可以等待接收功能。准备好将数据发送到客户端时,可以等待发送功能,然后将要发送给客户端的任何数据传递给客户端。让我们看一下这在示例应用程序中是如何工作的。

 

创建一个ASGI应用

在我们的asgi.py文件中,我们将使用我们自己的ASGI应用程序包装Django的默认ASGI应用程序功能,以便自己处理Websocket连接。为此,我们需要定义一个名为application的异步函数,该函数需要3个ASGI参数:scope,receive和send。将get_asgi_application调用的结果重命名为django_application,因为我们需要它处理HTTP请求。在我们的应用程序函数内部,我们将检查scope [‘type’]的值以确定请求类型。如果请求类型为“ http”,则该请求为普通的HTTP请求,我们应该让Django处理它。如果请求类型为“ websocket”,那么我们将自己处理逻辑。

 

在views.py的同级目录,创建文件asgi.py,内容如下:

# !/usr/bin/python3
# -*- coding: utf-8 -*-
import osfrom django.core.asgi import get_asgi_application# 注意修改项目名
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django3_websocket.settings')django_application = get_asgi_application()async def application(scope, receive, send):if scope['type'] == 'http':# Let Django handle HTTP requestsawait django_application(scope, receive, send)elif scope['type'] == 'websocket':# We'll handle Websocket connections herepasselse:raise NotImplementedError(f"Unknown scope type {scope['type']}")

 

在views.py的同级目录,创建文件websocket.py,内容如下:

async def websocket_application(scope, receive, send):while True:event = await receive()if event['type'] == 'websocket.connect':await send({'type': 'websocket.accept'})if event['type'] == 'websocket.disconnect':breakif event['type'] == 'websocket.receive':if event['text'] == 'ping':await send({'type': 'websocket.send','text': 'pong!'})

 

现在,我们需要创建一个函数来处理Websocket连接。 在与asgi.py文件相同的文件夹中创建一个名为websocket.py的文件,并定义一个名为websocket_application的ASGI应用程序函数,该函数接受3个ASGI参数。 接下来,我们将在我们的asgi.py文件中导入websocket_application,并在我们的应用程序函数内部调用它来处理Websocket请求,传入范围,接收和发送参数。 它看起来应该像这样:

import osfrom django.core.asgi import get_asgi_application
# 注意修改应用名
from web.websocket import websocket_applicationos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'websocket_app.settings')django_application = get_asgi_application()async def application(scope, receive, send):if scope['type'] == 'http':await django_application(scope, receive, send)elif scope['type'] == 'websocket':await websocket_application(scope, receive, send)else:raise NotImplementedError(f"Unknown scope type {scope['type']}")

接下来,让我们为Websocket应用程序实现一些逻辑。我们将监听所有Websocket连接,当客户端发送字符串“ ping”时,我们将以字符串“ pong!”进行响应。

在websocket_application函数内部,我们将定义一个不确定的循环,该循环将处理Websocket请求,直到关闭连接。在该循环内,我们将等待服务器从客户端收到的任何新事件。然后,我们将根据事件的内容采取行动,并将响应发送给客户端。

首先,让我们处理连接。当新的Websocket客户端连接到服务器时,我们将收到“ websocket.connect”事件。为了允许这种连接,我们将发送一个“ websocket.accept”事件作为响应。这将完成Websocket握手并与客户端建立持久连接。

当客户端终止其与服务器的连接时,我们还需要处理断开连接事件。为此,我们将监听“ websocket.disconnect”事件。当客户端断开连接时,我们将摆脱不确定的循环。

最后,我们需要处理来自客户端的请求。为此,我们将监听“ websocket.receive”事件。当我们从客户端收到“ websocket.receive”事件时,我们将检查event [‘text’]的值是否为“ ping”。如果是,我们将发送一个’websocket.send’事件,其文本值为’pong!’。

 

测试

现在,我们的ASGI应用程序已设置为处理Websocket连接,并且我们已经实现了Websocket服务器逻辑,让我们对其进行测试。 目前,Django开发服务器不使用asgi.py文件,因此您将无法使用./manage.py runserver测试连接。 相反,您需要使用ASGI服务器(例如uvicorn)运行该应用程序。 让我们安装它:

pip3 install uvicorn

安装uvicorn后,我们可以使用以下命令运行ASGI应用程序:

注意:打开cmd控制台,切换到项目django3_websocket目录,执行命令

uvicorn web.asgi:application

输出:

?[32mINFO?[0m:     Started server process [?[36m15320?[0m]
?[32mINFO?[0m:     Waiting for application startup.
?[32mINFO?[0m:     ASGI 'lifespan' protocol appears unsupported.
?[32mINFO?[0m:     Application startup complete.
?[32mINFO?[0m:     Uvicorn running on ?[1mhttp://127.0.0.1:8000?[0m (Press CTRL+C to quit)

 

如果出现以下报错:

    'DIRS': [os.path.join(BASE_DIR, 'templates')]
NameError: name 'os' is not defined

请修改settings.py,在顶头部分,导入os模块。

import os

再次执行uvicorn 命令即可。

 

访问页面

http://127.0.0.1:8000

效果如下:

 

 

 

要测试Websocket连接,请在新选项卡中打开浏览器的开发工具。 在控制台中,创建一个名为ws的新Websocket实例,该实例指向ws:// localhost:8000 /。 然后将onmessage处理程序附加到将event.data记录到控制台的ws。 最后,调用ws.send(’ping’)将消息发送到服务器。 您应该看到值“ pong!”。 登录到控制台。

请依次输入以下命令:

ws = new WebSocket('ws://localhost:8000/')
ws.onmessage = event => console.log(event.data)
ws.send("ping")

效果如下:

 

 恭喜! 现在,您知道了如何使用ASGI将Websocket支持添加到Django应用程序中。 去用它来制作很棒的东西。

 

本文参考链接:

https://www.mindg.cn/?p=2489

 


http://chatgpt.dhexx.cn/article/TRYyQtWv.shtml

相关文章

websockets_WebSockets简介

websockets WebSockets are an alternative to HTTP communication in Web Applications. WebSocket是Web应用程序中HTTP通信的替代方法。 They offer a long lived, bidirectional communication channel between client and server. 它们在客户端和服务器之间提供了长期的双…

尝试Python的websockets库的最基础功能

目标 尝试最简单的代码创建一个服务器并在客户端收发信息。 主要参考的是官方文档的首页:https://websockets.readthedocs.io/ (还需要 asyncio 库的一些知识,可见之前的博客 翻译《使用asyncio的一个指南》作者:Andrew Crozier…

python使用websockets库

python使用websockets库 serve:在server端使用,等待客户端的连接。如果连接成功,返回一个websocket。 connect: 在client端使用,用于建立连接。 send:发送数据 recv:接收数据 close:关闭连接 服务端 #!/usr/bin/python3 # 主要功能&am…

什么是WebSockets!?

到目前为止,我们已经深入到实时世界,因为许多应用程序使用实时数据。 现在正是以技术立场解释所有导致这一点的事件的时候了。 所以,这里...... 目前,应用程序正在从利用数据库中的陈旧数据或在实际事件之后的实时体验中事…

WebSockets介绍

Web sockets定义为在servers和clients之间的双向连接。意味着servers和clients可以同时交流并发送数据。这种协议是从底层就是双工连接。Web sockets技术上得到了质的飞跃。 握手是一个过程,确保server与client同步。握手是Web Socket protocol的基础概念。 下面的图…

websockets_将WebSockets与Node.js结合使用

websockets WebSockets are an alternative to HTTP communication in Web Applications. WebSocket是Web应用程序中HTTP通信的替代方法。 They offer a long lived, bidirectional communication channel between client and server. 它们在客户端和服务器之间提供了长期的双…

各大公司数据结构与算法面试题解答(一)

还有一年就要找工作了,从现在开始找些公司的数据结构和算法的题来做一做,不定时贴出笔试面试题代码。 1.创新工场: 求一个数组的最长递减子序列比如{9,4,3,2,5,4,3&…

数据结构面试题整理

一 数据结构 1.你熟悉什么数据结构? 数组 链表 栈 队列 哈希 二叉树 二叉查找树 二叉堆 b树 b树 2.b树 b树 b*树 b和b都是节点可以有很多子节点,区别是b树所有的节点都可以存储关键字,而b树只有叶子节点存储关键字,适用于数据库…

数据结构与算法三十题,弄懂这些面试就够了!

https://www.toutiao.com/a6649963989537128967/ 2019-01-24 15:36:35 国外 IT 教育学院 Educative.io 创始人 Fahim ul Haq 写过一篇过万赞的文章《The top data structures you should know for your next coding interview》,总结了程序员面试中需要掌握的 8 种数据结构知识…

数据结构与算法面试知识点汇总(超全)

文章目录 一、哈希函数和哈希表01 哈希函数02 哈希表 二、布隆过滤器三、一致性哈希四、并查集01 具体实现02 优化03 代码实现 五、前缀树(trie树)六、B树和B树七、线段树01 线段树的优势02 线段树实现 一、哈希函数和哈希表 01 哈希函数 哈希函数&…

《数据结构》十道链表经典面试题多种方法深度解析

目录 ⛰️一、题目解析 🗻1.1删除链表中等于给定值 val 的所有节点(力扣) 🗻1.2反转一个单链表。(力扣) 🗻1.3给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有…

数据结构和算法常见面试问题总结,含答案

0. 写在前面 总导航在此 这些问题是我备考数据结构和算法的过程中,详细总结的常见面试问题和答案。逐个搜索并记录下来,花了很大的精力!如果想要获取源文件的话,可以关注我的微信公众号:小梁说代码,获取嘿…

(六)数据结构面试必问

什么是链表、队列、栈? 链表: 当需要存储多个相同数据类型的时候,可以使用数组存储,数组可以通过下标直接访问,但数组有个缺点就是无法动态的插入或删除其中的元素(特别是操作第一个位置上的元素&#xff…

数据结构常见面试题

链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,也适合考察写代码的能力。链表的操作也离不开指针,指针又很容易导致出错。综合多方面的原因,链表题目在面试中…

面试中常见的数据结构

上次在面试时被面试官问到学了哪些数据结构,那时简单答了栈、队列/(ㄒoㄒ)/~~其它就都想不起来了,今天有空整理了一下几种常见的数据结构,原来我们学过的数据结构有这么多~ 首先,先来回顾下C语言中常见的基本数据类型吧O(∩_∩)O …

数据结构算法常见面试考题

(1) 红黑树的了解(平衡树,二叉搜索树),使用场景 把数据结构上几种树集中的讨论一下: 1.AVLtree 定义:最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为…

八大数据结构及常见面试题

几乎所有的问题都需要面试者对数据结构有深刻的理解。无论你是初入职场的新兵(刚从大学或者编程培训班毕业),还是拥有几十年经验的职场老鸟。 即便是对于一些非常基础的工作来说,学习数据结构也是必须的。那么,就让我们先从一些基本概念开始入…

数据结构面试、数据结构考研复试——常见问题以及回答

说明:这些是自己整理回答的答案 可以借鉴 也可能存在错误 欢迎指正 文章目录 逻辑结构与物理结构的区别算法常见的数据结构链表存储结构和顺序存储结构的区别数组和链表的区别头指针和头结点的区别线性链表判断整个链表是否有环,如何找到这个环单链表和…

架构设计分布式数据结构与算法面试题(2020最新版)

Java面试总结(2021优化版)已发布在个人微信公众号【技术人成长之路】,优化版首先修正了读者反馈的部分答案存在的错误,同时根据最新面试总结,删除了低频问题,添加了一些常见面试题,对文章进行了…

数据结构面试题以及答案整理

参考网络整理的一些问题 一、什么是数据结构? 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。结构包括逻辑结构和物理结构。 数据的逻辑结构包括4种 (1)集合:数据元素之间除了有相同的数据类…