Django ASGI服务

news2024/9/23 17:20:35

1. ASGI简介

在Django中, ASGI(Asynchronous Server Gateway Interface)的引入使得Django应用能够支持异步编程.
从Django 3.0开始, Django就增加了对ASGI的支持, 但直到Django 3.1才正式推荐在生产环境中使用ASGI.
ASGI是一个用于Python的异步Web服务器的标准接口, 它允许你运行异步的Django应用.
要启动Django的ASGI服务器, 通常需要使用一个支持ASGI的服务器, 如Daphne, Uvicorn或Hypercorn.
以下是使用Uvicorn作为ASGI服务器来启动Django应用的基本步骤:
* 1. 确保Django版本: 首先, 确保Django版本是3.1或更高, 因为这些版本才正式支持ASGI.
* 2. 设置ASGI应用: 在Django项目的settings.py文件中, 确保已经设置了ASGI_APPLICATION变量,
     它应该指向项目中的asgi.py文件中的application对象.
# settings.py  

# awsi配置
ASGI_APPLICATION = 'MyDjango.asgi.application'
# 这里的'your_project'是Django项目的名称.
* 3. 检查asgi.py: 在Django项目的根目录下, 有一个asgi.py文件.
     这个文件是Django自动生成的, 用于配置ASGI应用, 它通常看起来像这样:
# asgi.py  
import os  
from django.core.asgi import get_asgi_application  

# 确保这个文件中的DJANGO_SETTINGS_MODULE环境变量正确设置为了项目设置模块.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyDjango.settings')  
 
application = get_asgi_application()

* 4. 安装ASGI服务器: 接下来, 需要安装一个ASGI服务器.
     以Uvicorn为例, 可以通过pip安装它: pip install uvicorn
* 5. 启动ASGI服务器: 最后, 使用Uvicorn(或其他ASGI服务器)来启动你的Django应用.
     在命令行中, 运行命令: uvicorn MyDajngo.asgi:application --host 0.0.0.0 --port 8000 .
     这里的'MyDajngo'是的Django项目的名称,
     --host 0.0.0.0表示服务器将监听所有可用的网络接口, --port 8000指定了服务器将使用的端口号.
     注意: 在settings.py文件中设置了ASGI_APPLICATION = 'MyDjango.asgi.application', 是可以直接通过快捷按钮启动的.

2024-08-05_142033

* 6. 访问应用: 现在, Django应用已经以异步方式在ASGI服务器上运行了.
     可以在浏览器中访问: http://127.0.0.1:8000 来查看应用.
由于ASGI是异步的, 需要修改视图和其他代码来利用异步编程的优势.
Django的ORM本身并不支持异步操作, 因此如果需要在异步视图中进行数据库操作, 
可能需要使用支持异步的数据库客户端库, 如databases或aiopg.

此外, 虽然ASGI为Django应用带来了异步编程的可能性, 但它并不是必需的.
如果应用不需要异步特性, 仍然可以像往常一样使用WSGI服务器(如Gunicorn或uWSGI)来运行你的Django应用.
Django的路由系统(URLs)和视图(Views)是以同步方式编写的, 即使使用ASGI来运行Django应用.
然而, 对于需要异步处理的功能, 如WebSocket连接和异步HTTP请求, 使用Django Channels是一个很好的解决方案.

2. Channels简介

Channels是一个允许编写异步消费者(consumers)的框架, 这些消费者可以处理WebSocket连接, 异步HTTP请求等.
Channels建立在ASGI之上, 允许编写真正的异步代码, 而不会阻塞Django的事件循环.
Channels提供了与Django路由系统相似的机制, 但它专注于异步操作.
在Channels中定义路由将不同的协议(: HTTP, WebSocket)和路径映射到相应的异步消费者上.
以下是如何在Django项目中设置Channels的基本步骤:
* 1. 安装 Channels: pip install channels .
* 2. 修改项目的settings.py.
     将channels添加到INSTALLED_APPS中.
     设置ASGI_APPLICATION指向ASGI配置文件.
     由于Channels的功能依赖于Redis数据库, 因此还需要在settings.py中设置Channels的功能配置.
# settings.py
INSTALLED_APPS = [  
    ...  
    'channels',
]

# ASGI配置
ASGI_APPLICATION = 'MyDjango.routing.application'

# Channels配置
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],  # Redis配置
        },
    },
}

image-20240805180204518

* 3. 执行数据迁移, 因为Channels需要使用Django内置的会话Session机制, 用于区分和识别每个用户的身份信息.
     执行: Python manage.py migrate .

image-20240805173035391

* 4. 在应用中定义Channels路由.
     在应用目录下创建一个routing.py文件, 并定义WebSocket路由.
# routing.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from index import routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyDjango.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            routing.websocket_urlpatterns
        )
    ),
})

image-20240805173601709

* 5. 设置WebSocket URL模式.
     在路由文件中定义WebSocket的URL模式.
# MyDjango的urls.py
from django.urls import path, include
from .consumers import IndexConsumer

# 同步视图
urlpatterns = [
    path('', include(('index.urls', 'index'), namespace='index'))
]


# 异步视图
websocket_urlpatterns = [
    # 调用as_asgi()启动异步视图
    path('ws/index/', IndexConsumer.as_asgi()),
]

image-20240805175751860

* 6. 编写消费者.
     在应用目录下创建一个consumers.py文件, 并编写异步消费者.
# index/consumers.py
from channels.generic.websocket import AsyncWebsocketConsumer
import json


class IndexConsumer(AsyncWebsocketConsumer):

    # 连接
    async def connect(self):
        print("一个客户端连接了服务器")
        await self.accept()  # 接受传入套接字

    # 断开
    async def disconnect(self, close_code):
        print("一个客户端断开了连接")
        pass

    # 收到, 接收从 WebSocket 发送的消息
    async def receive(self, text_data=None, bytes_data=None):
        text_data_json = json.loads(text_data)  # 反序列化文本数据
        message = text_data_json['message']  # 取出聊天信息
        print(message)

        # 发送消息到 WebSocket
        await self.send(text_data=json.dumps({  # 序列化聊天信息
            'message': message
        }))

image-20240805175827206

异步方法的调用机:
* connect()方法: 当WebSocket客户端尝试连接到服务器时, Channels会自动调用connect()方法.
  可以在这个方法中执行一些初始化操作, 比如验证客户端身份, 设置会话变量等, 并通过调用await self.accept()来接受连接.
* disconnect()方法: 当WebSocket连接关闭时, Channels会自动调用disconnect()方法.
  可以在这个方法中执行一些清理操作.
* receive()方法: 当WebSocket客户端发送消息到服务器时, Channels会自动调用receive()方法, 并将接收到的消息作为参数传递.
  需要在这个方法中处理接收到的消息, 并可能通过await self.send()或await self.send_json()等方法向客户端发送响应.

3. WebSocket介绍

在Django Channels中, WebSocket并不是通过传统的HTTP请求来访问的, 
因此不能直接通过浏览器地址栏(如输入:http://localhost:8000/ws/my-endpoint/)来访问WebSocket端点.

WebSocket是一种在单个TCP连接上进行全双工通讯的协议, 它允许服务器和客户端之间建立持久的连接, 并通过这个连接进行数据的双向传输.
浏览器可以通过JavaScript的WebSocket API来建立与WebSocket服务器的连接.
这个API允许创建一个WebSocket对象, 并指定要连接的URL.
注意, 这个URL应该以: ws://(非加密)或wss://(加密)开头, 而不是 http://或https://.
然后, 可以使用这个对象来发送和接收数据.
以下是一个简单的例子, 展示了如何在浏览器中使用JavaScript来连接WebSocket服务器:
* 1. 编写路由, 后续可以通过: 127.0.0.1:8000 , 触发index视图函数.
# index/urls.pu
from django.urls import path
from .views import *

urlpatterns = [
    # 访问异步视图
    path('', index, name='index'),
]

image-20240805174722899

* 2. 编写视图函数.
     在视图函数中放回一个模板页码.

image-20240805174829703

* 3. 编写模板页面.
     在模块页面中编写js代码, 使用WebSocket API来建立与WebSocket服务器的连接.
<!-- tempaltes的index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>访问异步视图</title>
</head>
<body>
<p>访问: 异步视图...</p>
<script>
    // 生成一个WebSocket对象
    var chatSocket = new WebSocket('ws://' + window.location.host + '/ws/index/');

    // 监听连接打开事件
    chatSocket.onopen = function (event) {
        console.log('WebSocket连接成功');
        // 连接建立后发送消息
        chatSocket.send(JSON.stringify({
            'message': '你好!'
        }));
    };

    // 接收信息
    chatSocket.onmessage = function (e) {
        try {
            var data = JSON.parse(e.data);
            var message = data['message'];
            alert(message);
        } catch (error) {
            console.error('解析消息时出错:', error);
        }
    };

    // 处理连接关闭事件
    chatSocket.onclose = function (event) {
        if (event.wasClean) {
            console.log('WebSocket连接正常关闭');
        } else {
            console.error('WebSocket连接异常关闭');
        }
        console.log('关闭代码:', event.code, '关闭原因:', event.reason);
    };

    // 处理连接错误事件
    chatSocket.onerror = function (error) {
        console.error('WebSocket发生错误:', error);
    };
</script>
</body>
</html>

image-20240805180443327

* 4. 启动项目, 访问: 127.0.0.1:8000 , 执行index视图函数.
     视图函数返回的页面会执行js代码先访问: ws://127.0.0.0:8000/ws/index/ , 执行异步视图.

image-20240805180626250

结论: 通过Django Channels, 可以编写异步的WebSocket消费者和其他类型的异步协议处理器, 从而充分利用ASGI的优势.
虽然Django的路由系统(URLs)和视图(Views)主要用于同步操作, 但Channels提供了与Django路由相似的机制, 专门用于异步操作.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1982099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图解RocketMQ之消息如何存储

大家好&#xff0c;我是苍何。 人一辈子最值得炫耀的不应该是你的财富有多少&#xff08;虽然这话说得有点违心&#xff0c;呵呵&#xff09;&#xff0c;而是你的学习能力。技术更新迭代的速度非常快&#xff0c;那作为程序员&#xff0c;我们就应该拥有一颗拥抱变化的心&…

西安交通大学先进动力与新能源发展峰会举行

8月3日&#xff0c;西安交通大学第十届先进动力与新能源发展峰会暨西安交大先进动力校友会2024年年会在深圳举行。西安交通大学党委常委、副校长单智伟&#xff0c;南方科技大学清洁能源研究院院长、创新创业学院院长、澳大利亚国家工程院外籍院士刘科&#xff0c;西安交通大学…

抑制电机噪声的又一神器 -- 三线共模电感

概述 针对电机产品&#xff0c;尤其是三相无刷电机&#xff0c;如图1&#xff0c;其噪声源主要是电机的开关驱动模块&#xff08;具体可参阅另一篇文章“”&#xff09;&#xff0c;而一般的等效天线即为连接电机与驱动板的电机线&#xff08;等效天线、四分之一波长的理论解释…

R18 NTN中的Satellite switch with re-sync过程

更多精彩内容,请阅知识星球合集链接。该链接收录了目前知识星球所有内容,涵盖了5G相关领域的绝大多数知识点;主要以协议原文截图后进行解释讲解外加实网log对照为主,辅以星友问答等等精华内容。 合集链接如下(不用登录飞书即可查看):Docs 如果您对3GPP spec阅读有困扰; 如…

HTTPS 比 HTTP 更安全吗?这两种协议有什么区别?

在互联网的通讯过程中&#xff0c;HTTP&#xff08;超文本传输协议&#xff09;和HTTPS&#xff08;安全HTTP&#xff09;是两种最基本、最重要的通讯协议&#xff0c;它们在网络中都扮演着重要的角色。然而近年来&#xff0c;随着网络安全问题的日益突出&#xff0c;HTTPS的安…

测试人员怎么通过浏览器开发工具 Performance 分析性能

在现代Web开发中&#xff0c;性能优化是一个永恒的话题。对于测试人员来说&#xff0c;如何有效地使用浏览器开发工具中的Performance面板&#xff0c;进行性能分析和调优&#xff0c;是一项必备技能。本文将带你深入了解浏览器开发工具Performance面板的使用方法及其在性能测试…

OrangePi AIpro学习2 —— 配置昇腾DVPP环境

目录 一、clone需要运行的软件 二、运行corp程序 2.1 解决缺少sample_common.sh 2.2 解决缺少INSTALL_DIR环境变量 2.3 运行程序 三、测试其他程序 3.1 程序目录 3.2 程序注意事项 3.3 如何找出报错原因 一、clone需要运行的软件 1. 软件地址 samples: CANN Samples…

Docker 设置代理

Docker 设置代理 创建配置文件 sudo mkdir -p /etc/systemd/system/docker.service.d sudo touch /etc/systemd/system/docker.service.d/proxy.conf sudo vim /etc/systemd/system/docker.service.d/proxy.conf 编辑代理配置 #输入以下内容&#xff0c;其中代理改成自己的…

【大小球让球实战】——深度剖析足球大小球数据分析软件,找到一个临界点,把准确率提高到70%?

最近在跟一些圈内朋友聊天&#xff0c;发现每个人都有一套自己的玩球逻辑&#xff0c;比如有些人看亚盘&#xff0c;有些看欧盘&#xff0c;有些玩绝杀&#xff0c;有些看盘口&#xff0c;是否可以自定义的去玩球&#xff1f;结合多年的经验&#xff0c;把分析的过程大概写了一…

ESP32在ESP-IDF环境下禁用看门狗

最近使用了一款ESP32的开发板。但在调试时发现出现许多看门狗复位事件&#xff1a; E (8296) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time: E (8296) task_wdt: - IDLE (CPU 0) E (8296) task_wdt: Tasks curre…

FFmpeg 7.0重大更新

0、维护工作 对于任何成熟的软件&#xff0c;每个版本必然包含大量的bugfix、cleanup。维护工作不会出现在Changelog中&#xff0c;不是吸引眼球的东西&#xff0c;但是人力投入的占比最高&#xff0c;是一个项目长期稳定的保证。 维护工作必须得提两个人&#xff0c;Andreas…

校园超市收银软件的挑战:双系统困境-亿发

在现代零售业中&#xff0c;高效的管理系统是确保业务顺利进行的关键。然而&#xff0c;对于学校直属管理的超市来说&#xff0c;选择合适的收银系统往往是一项挑战。由于缺乏能够同时满足收银和进销存管理需求的高适配性系统&#xff0c;许多学校超市不得不同时使用两套系统&a…

iPhone手机清理软件:让你的设备焕然一新

随着智能手机在我们生活中的地位日益重要&#xff0c;保持设备的最佳性能就显得尤为关键。对于iPhone用户而言&#xff0c;随着时间的推移&#xff0c;手机可能会因累积了过多的缓存文件、重复照片、未使用的应用和各种其他数据而变得缓慢。幸运的是&#xff0c;市面上有多种iP…

可以翻页、互动、留言和弹幕的仿真电子相册制作方法

​在数字化时代&#xff0c;仿真电子相册作为一种结合了翻页、互动、留言和弹幕等多种功能的创意表达形式&#xff0c;正逐渐成为人们记录生活和分享回忆的重要方式。本教程将介绍如何利用FLBOOK这款强大的电子相册制作工具&#xff0c;制作具有这些特性的令人印象深刻的作品。…

ICM-20948芯片详解(6)

接前一篇文章&#xff1a;ICM-20948芯片详解&#xff08;5&#xff09; 五、组件概览及详述 再次给出ICM-20948芯片的内部结构框图&#xff1a; 2. 组件详述 &#xff08;6&#xff09;辅助I2C串行接口 ICM-20948具有用于与外部传感器通信的辅助I2C总线。该总线有两种操作模…

实时采集同花顺要闻直播资讯

采集同花顺要闻直播资讯能实时掌握市场动态、政策变化及企业新闻&#xff0c;对投资者而言&#xff0c;有助于及时做出投资决策&#xff0c;把握市场机会&#xff0c;规避风险。对于研究机构和媒体&#xff0c;它提供一手资料&#xff0c;支持深度分析与报道。 采集网址&#x…

第 8 章 虚拟文件系统(7)

目录 8.5 标准函数 8.5.1 通用读取例程 8.5.2 失效机制 8.5.3 权限检查 8.6 小结 本专栏文章将有70篇左右&#xff0c;欢迎关注&#xff0c;查看后续文章。 8.5 标准函数 大多数文件系统中 file_operations 的 read&#xff0c;write 分别为&#xff1a; do_sync_read&am…

Android开发之事件分发

#来自ウルトラマンゼロ&#xff08;哉阿斯&#xff09; 1 Activity 构成 平常布局展示在ContentView中。 2 事件分发 事件分发的本质其实就是把事件&#xff08;Touch&#xff09;封装成 MotionEvent 类&#xff0c;然后传递给 View 的层级处理。 MotionEvent 事件类型主要有…

51单片机-第七节-DS1302实时时钟

一、DS1302介绍&#xff1a; 实时时钟芯片&#xff0c;可对年&#xff0c;月&#xff0c;日&#xff0c;周&#xff0c;时&#xff0c;分&#xff0c;秒计时&#xff0c;是一种集成电路。 二、DS1302原理&#xff1a; 1.寄存器定义&#xff1a; Command&#xff1a;操作模式…

MySQL:表的增删查改——CRUD(二)

本篇博客接上篇&#xff1a;MySQL&#xff1a;表的增删查改——CRUD&#xff08;一&#xff09;-CSDN博客 目录 1、查询&#xff08;Retrieve&#xff09; 1.1 条件查询&#xff1a;WHERE 1.1.1 比较运算符 1.1.2 逻辑运算符 1.1.3 查询语句的执行顺序 1.1.3 SQL代码示例…