如何在 Django框架下完成 websocket 连接 在 Heroku 上部署 websocket 应用

news2024/11/27 12:20:08

文章目录

  • websocket 和 socket 连接的区别
  • 与 Django 建立 websocket 连接
    • ASGI v.s. WSGI
      • Django > 3.0
      • Channels
      • Daphne
      • settings.py
      • consumers.py & routing.py
  • 测试 websocket 连接
    • postman
  • Heroku 部署 websocket 应用
    • asgi.py
    • Procfile

websocket 和 socket 连接的区别

  • Websocket 和 Socket 是两种不同的通信协议,都是用于建立网络连接的方式,但它们各有特点和适用场景。以下是它们之间的主要区别。

  • Websocket

    1. 双向通信: Websocket 协议可以实现客户端与服务器的双向通信,在任何时候,只要对方在线,客户端和服务器都可以主动发起通讯。

    2. 基于 HTTP 握手: 创建 Websocket 连接需要通过 HTTP 协议进行一次握手。一旦这个握手完成,后续数据传输就直接在 Websocket 连接上进行,不再依赖 HTTP 。

    3. 更少的数据传输开销: 在建立好连结后,数据帧头部介于2-14 bytes之间,相较于HTTP每次请求响应的头部至少为500-800 bytes来说,传输成本大大降低。

    4. 全双工模式: 在建立的连接上,客户端和服务器可以同时发送或接收数据。

    5. 实时通信: 由于其双向性,Websocket 更适合需要高频率、低延迟的实时交互场景,例如在线聊天、股票交易等。

  • Socket

    1. 底层协议: Socket 是更底层的通信协议,它基于 TCP/IP 或 UDP ,能够实现全双工通信。

    2. 高度灵活: Socket 提供了一种控制网络通信的方法,用户可以根据需要自定义协议来满足特定的通信需求。

    3. 多种连接类型: Socket 支持多种连接类型,包括 TCP、UDP、RAW SOCKET 等。

    4. 易于理解和使用: 相比于 Websocket,Socket 的原理和使用更为简单,是学习网络编程的基础。

    5. 广泛应用: Socket 被广泛用于各种网络服务中,如 FTP、POP3、TELNET 等。

总的来说,Websocket 和 Socket 都有各自的优点和缺点,选择哪种协议取决于具体的应用需求。

与 Django 建立 websocket 连接

ASGI v.s. WSGI

  • ASGI (Asynchronous Server Gateway Interface) 和 WSGI (Web Server Gateway Interface) 都是 Python 的 web 服务器规范。以下是它们的主要区别。

  • WSGI

    1. 同步处理: WSGI 是一个同步接口,它假设应用程序将一次处理一个请求,并且在处理下一个请求之前完成当前请求。

    2. 成熟稳定: WSGI 是 Python 中最常用的 web 服务器规范,支持大量库和中间件,如 Flask 和 Django 等。

    3. 对 HTTP/1.0 有良好的支持: 使用 WSGI,可以轻松地进行基于 HTTP/1.0 的通信。

    4. 对长连接和 WebSocket 支持不佳: 由于是同步的,WSGI 不适合处理长时间运行的连接或需要并发处理多个请求的场景(如 WebSockets 或长轮询)。

  • ASGI

    1. 异步处理: ASGI 是一个异步接口,能够处理 并发请求,提高了应用程序的性能。

    2. 更广泛的协议支持: ASGI 不仅支持 HTTP,还可以处理其他协议,包括 WebSocket 和 HTTP/2 等。

    3. 对长连接和 WebSocket 有良好的支持: ASGI 支持异步 IO,因此非常适合处理长连接、WebSocket 连接,以及其他需要并发处理的场景。

    4. 为新的框架提供基础: ASGI 在一些新的 Python web 框架中得到了应用,例如 Starlette 和 FastAPI 等。

  • 因此在当前场景中我们要构建基于 Websocket 的连接,自然就要使用基于 ASGI 的配置方式

  • 在 Django 中,默认是使用 WSGI 的应用,因此为了配置 ASGI 应用,我们需要进行以下文件的改变

Django > 3.0

  • 升级 Django 版本: 从 Django 3.0 开始,Django 开始支持 ASGI。请确保你的 Django 版本至少是 3.0。

Channels

  • 安装 Channels: Django 需要使用 Channels 库以支持 ASGI。你可以通过 pip 安装 Channels。
    pip install channels
    

Daphne

  • Daphne 是一个由 Django Channels 项目开发的 HTTP、HTTP2 和 WebSocket 协议的 ASGI (Asynchronous Server Gateway Interface) 服务器。它的主要作用是 将请求从客户端转发到 Django Channels 或其他 ASGI 应用,并将响应返回到客户端

  • 以下是 Daphne 的一些关键特性:

    • 支持多种协议: Daphne 支持 HTTP/1.1、HTTP/2 和 WebSocket 这三种协议,对于需要实时通信的 web 应用来说这是非常重要的。

    • 并发处理: 使用基于事件的服务器模型,Daphne 可以同时处理大量的连接和请求,而不会阻塞服务。

    • 兼容 Django Channels: Daphne 与 Django Channels 完全兼容,可以直接运行 Django Channels 应用。

    • 扩展性: 你可以通过在 Django Channels 中添加自定义的通道层,使 Daphne 能够支持更复杂的使用场景,如广播消息或跨进程通信等。

  • 总的来说,如果你正在构建一个 Django Channels 应用,或者你的 Python 应用需要使用 ASGI,那么 Daphne 就能派上用场。

    pip install daphne
    
  • daphne 也需要配置到 settings.pyINSTALLED_APPS 中:
    在这里插入图片描述

settings.py

  • 添加 Channels 到 INSTALLED_APPS: 在你的 settings.py 文件中,将 channels 添加到 INSTALLED_APPS 列表中:
    INSTALLED_APPS = [
        # ...
        'channels',
    ]
    
  • 设置 ASGI_APPLICATION: 在 settings.py 文件中设置 ASGI_APPLICATION 路径(原本 settings.py 中没有这个,需要自己手动添加一项)。
    ASGI_APPLICATION = 'YOUR_PROJECT_NAME.routing.application'
    

在这里插入图片描述

consumers.py & routing.py

  • 在你的项目根目录下(与 settings.py 同一个目录),创建一个 routing.py 文件,并定义你的 websocket 访问的功能的相关路由,这里要使用 ProtocolTypeRouterURLRouter 来构建。
    在这里插入图片描述

  • 接下来如同我们在 views.py 中定义视图函数来处理 socket 连接的请求,我们在 consumers.py(新创建一个)中处理 websocket 连接的相关逻辑,这个代码根据自己想实现的内容去写对应的功能即可:
    在这里插入图片描述

测试 websocket 连接

postman

  • 首先在 ① 的位置选择 websocket 连接方式
  • 在 ② 中输入自己 Django 中定义的路由
  • send 看是否能够连接成功
    在这里插入图片描述

Heroku 部署 websocket 应用

  • 以上是当你在本地部署一个 websocket 应用需要完成的步骤,这个部分,我会讲解如何在 Heroku 上基于上述的改变来成功部署 websocket 应用

asgi.py

  • 上面我们已经通过一个 routing.py 来定义了 websocket 的相关路由,在部署的时候我更推荐不使用 routing.py 而是通过 asgi.py 文件来定义路由:

    from channels.routing import ProtocolTypeRouter, URLRouter
    from django.core.asgi import get_asgi_application
    from django.urls import path
    from nnsh_backend_new import consumers  # Replace with your actual app name
    
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
    
    application = ProtocolTypeRouter({
        "http": get_asgi_application(),
        'websocket': URLRouter([
            path('ws/room/<str:room_name>/', consumers.RoomConsumer.as_asgi()),
        ]),
    })
    
  • 注意,这里添加了 "http": get_asgi_application(),这将 HTTP 请求委托给 Django 的 ASGI 应用程序。WebSocket 请求则会被传递给你定义的 URLRouter

  • 总之,为你的 Django Channels 项目创建一个 asgi.py 文件是非常重要的,它告诉 ASGI 服务器如何处理各种类型的请求。没有它,你的 WebSocket 路由可能无法正常工作。

  • 在 Django Channels 中,你可以选择直接在 asgi.py 文件中定义路由,也可以选择在单独的 routing.py 文件中定义并在 asgi.py 中导入它。
    如果你的 WebSocket 路由比较简单,你可能觉得直接在 asgi.py 文件中定义更方便。但是,如果你有很多复杂的路由或者消费者,将他们放在单独的 routing.py 文件中可能会让你的代码更清晰和易于管理。
  • 以下是一个示例,展示如何在 asgi.py 文件中导入一个 routing.py 文件:
    # asgi.py文件
    
    import os
    from django.core.asgi import get_asgi_application
    from channels.routing import ProtocolTypeRouter, URLRouter
    import YOUR_PROJECT_NAME.routing  # 换成你的 app 名字
    
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'YOUR_PROJECT_NAME.settings')
    
    application = ProtocolTypeRouter({
        "http": get_asgi_application(),
        "websocket": URLRouter(
            yourapp.routing.websocket_urlpatterns
        ),
    })
    
  • 然后在 YOUR_PROJECT_NAME.routing 中定义你的 websocket 路由:
    # routing.py文件
    
    from django.urls import re_path
    
    from . import consumers
    
    websocket_urlpatterns = [
        re_path(r'ws/room/(?P<room_name>\w+)/$', consumers.RoomConsumer.as_asgi()),
    ]
    
  • 在这个项目中,我选择放弃在 routing.py 中定义任何内容,而是将所有路由相关的内容都写到 asgi.py

Procfile

  • 我们之前引入了 daphne 却实际上没有用到,这是因为我们只有在部署的时候才需要这个 daphne,他的作用是开启 asgi 应用

  • 在之前我们的 procfile 中定义的写法是:web: gunicorn YOUR_PROJECT_NAME.wsgi 这是通过 gunicorn 启动一个 wsgi 应用

  • 但是我们的 websocket 应用则需要通过 daphne 来开启

  • 所以我们将 Procfile 改成如下形式:

    release: python manage.py makemigrations nnsh_backend_new && python manage.py migrate
    web: daphne -p $PORT -b 0.0.0.0 nnsh_backend_new.asgi:application
    
  • 第二行中,我们通过 $PORT 告诉 Daphne 在所有网络接口的 Heroku 分配的端口上监听。
    在这里插入图片描述

  • 这样设置之后我们重新部署应用,然后通过 postman 发现这个 websocket 应用是可以正常工作的

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

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

相关文章

TLS、SSL、CA 证书、公钥、私钥

1. HTTP 的问题 HTTP 协议是超文本传输协议&#xff08;Hyper Text Transfer Protocol&#xff09;的缩写&#xff0c;它是从 WEB 服务器传输超文本标记语言 HTML 到本地浏览器的传送协议。HTTP 设计之初是为了提供一种发布和接收 HTML 页面的方法&#xff0c;时至今日&#x…

计算机组成原理(期末或考研备考)- 主存储器,DRAM,SRAM,ROM

讲解视频 SRAM VS DRAM DRAM工作原理 DRAM采用栅极电容上的电荷存储信息&#xff0c;由于DRAM上的电容电荷一般只能维持1-2ms&#xff0c;即使电源不断电&#xff0c;信息也会自动消失。因此每隔一定时间必须刷新。 集中刷新&#xff0c;利用固定的时间对所有的行进行刷新&am…

程序员和网络安全的优劣势一览表

程序员的优点&#xff1a; 学的都是计算机基础和一些程序语言&#xff0c;入门比较简单&#xff0c;无论什么行业参加几个月的培训找到一份月薪5K的工作还是没有问题的&#xff0c;人才的需求量虽然没有之前多&#xff0c;但是对真正有技术的人才需求还是挺大的。 程序员的缺…

Python_魔法属性和方法

目录 魔法属性 __doc__ __moudle__ __class__ __name__ __dict__ 魔法方法 __new__() __init__ () __del__() __call__() __str__ () __getitem__()&#xff0c;__setitem__(),__delitem__() __setattr__()、__getattr__&#xff08;&#xff09; __iter__() …

构建LLM应用你所要知道的事情;Midjourney可以生成图片外的场景

&#x1f989; AI新闻 &#x1f680; AI作画工具Midjourney推出新功能"Pan"&#xff0c;可以生成图片外的场景 摘要&#xff1a;AI作画工具Midjourney最近推出了"pan"功能&#xff0c;用户可以通过控制输入框中的"上下左右"来平移图片以生成场…

【案例】VR全景图:效果+源码

狠人话不多说,直接放视频效果地址 一、效果 1.视频效果 视频效果地址:点击这里 2.图片效果 二、构思 该怎么实现?页面如何布局页面是否可随意控制显示1.功能 控制页面显示数量可放大控制全景图+自动播放左右按钮控制上一页或下一页(尾页:下一页按钮隐藏,首页:上一页按…

Spring Boot 中的熔断器:原理和使用

Spring Boot 中的熔断器&#xff1a;原理和使用 什么是熔断器&#xff1f; 熔断器是一种用于处理分布式系统中故障的设计模式。它可以防止出现故障的服务对整个系统造成连锁反应。熔断器通过监控故障服务的调用情况&#xff0c;当故障服务出现问题时&#xff0c;熔断器会迅速…

【vue】Vue3中使用函数调用组件内函数和创建组件【超详细】

uniappuview vue3typescript版本&#xff0c;使用函数方式调用和创建组件&#xff0c;并使用组件内的方法 项目场景 今天突然觉得在视图上应用组件&#xff0c;然后在script脚本里操作组件这方式特别的麻烦。因为每次使用组件时都要进行应用&#xff0c;不管你用不用你都要引…

TDengine“露面”中国油气田企业智慧油田技术交流大会,为时序数据处理带来全新思路

2023 年 7 月 4 日- 6 日&#xff0c;由中国石油和化学工业联合会主办&#xff0c;中国石油油气和新能源分公司、中国石化油田勘探开发事业部、中国海洋石油有限公司勘探开发部协办的“中国油气田企业智慧油田技术交流大会”在北京市召开。本次大会邀请了中国石油、中国石化、中…

Android Studio实现内容丰富的安卓房屋出租租赁平台

如需源码可以添加q-------3290510686&#xff0c;也有演示视频演示具体功能&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动。 项目编号063 1.开发环境 android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.查看租房列表…

SSMP整合案例(12) 在界面中实现删除操作

接下来我们来说删除 首先 我们要在表格上加上删除和修改两个操作按钮 我们先在App.vue页面部分编写 参考代码如下 <el-table-columnalign"right"label"操作" ><template slot-scope"scope"><el-buttonsize"mini"type…

王道考研数据结构——基本概念

06 算法的时间复杂度 线性的时间复杂度 O(n^3)O(n^2*logn) O(n^3) O(logN) 无法确定&#xff0c;和输入的数据量有关系&#xff0c;使用平均复杂度&#xff1a; 最坏/平均时间复杂度 07 算法的空间复杂度 S(n)n S(n)O(n^2) 刷题&#xff1a; O(n^3) 答案&#xff1a; B…

Maven 配置本地jar,通过下载第三方jar包,然后手动配置maven jar包依赖 例如:IKExpression

说明&#xff1a;有时候有一些jar包 maven中央仓库和阿里云仓库没有收录的jar包需要手动下载至本地进行手动添加maven依赖&#xff0c;就拿 IK表达式 IKExpression jar 包来说 第一步 下载IKExpression 包 没有这个包的同学可以点击下载阿里云盘分享 第二步 找到自己项目本地…

vue3+elementUiplus开发的项目如何修改公共标签的默认颜色

背景:使用elementUiplus开发路由菜单栏需要更改默认颜色 步骤: 查看用到的变量 如:var(–el-menu-bg-color); 修改: index.scss文件下进行style的修改 :root {--el-color-primary: #0cba80 !important; // 主题色--el-color-primary-dark-2: #0cba80 !important;--el-color-…

datagrip連接mysql數據連接不上

昨天使用datagrip進行數據庫的連接時發現遲遲連接不上&#xff0c;問了老大才發現問題是&#xff1a; 在host中是無需要加入jdbc:mysql://這些的&#xff0c;只需要將wiltechs-based…放入host中即可

3D点云实战案例

sd推荐免费3D场景建模工具&#xff1a;NSDT场景编辑器 CloudCompare是一个三维点云&#xff08;网格&#xff09;编辑和处理软件。最初&#xff0c;它被设计用来对稠密的三维点云进行直接比较。它依赖于一种特定的八叉树结构&#xff0c;在进行点云对比这类任务时具有出色的性…

vue前端权限控制设计

概述 vue前端和后端程序是分离开发的&#xff0c;既然是分离的&#xff0c;vue前端怎么进行用户权限控制呢&#xff1f;本文介绍vue前端权限控制的方法&#xff0c;包括后端接口访问权限、页面操作按钮的权限、菜单的查看权限和vue路由的访问权限。 后端接口的访问权限 后端…

【服务器必备】Docker:使用容器技术,轻松部署应用

1、介绍 1.1 docker是什么&#xff1f;&#xff08;来自于维基百科&#xff09; Docker是一种流行的容器化技术&#xff0c;它能够帮助开发人员和运维人员更快、更轻松地部署和管理应用程序。通过使用Docker&#xff0c;您可以将应用程序及其依赖项打包到一个轻量级、可移植的…

spring系列-Spring Boot从初识到实战

Spring Boot从初识到实战 一、Hello Spring Boot 1、Spring Boot 简介 简化Spring应用开发的一个框架&#xff1b; 整个Spring技术栈的一个大整合&#xff1b; J2EE开发的一站式解决方案&#xff1b; 2、微服务 微服务&#xff1a;架构风格&#xff08;服务微化&#xff09; 一…

问你个问题,项目进度怎样控制才有效?

早上好&#xff0c;我是老原。 有多少项目经理&#xff0c;每天都被项目进度搞得焦头烂额。 对于项目经理们来说&#xff0c;最可怕的事情莫过于项目虽然还在&#xff0c;但时间却没了…… 试问谁不想把项目和进度都牢牢握在手里&#xff0c;享受运筹帷幄的感觉&#xff0c;…