FastAPI集成Socket.io坑点汇集和技术选型

news2024/9/18 18:22:00

背景

单纯的 websocket 通信方式存在大量的辅助性的工作需要处理,例如心跳机制、粘包处理、协议规范等,所以直接使用 websocket 开发,等于重复造轮子,毫无价值,而 socket.io 整理了一整套规范和机制,可以满足聊天室的功能,还能对不同的业务场景进行命名空间级别的隔离,简直不要太好用,完全满足我们这种低并发场景的各类需求且上手极其容易。

FastAPI 如何集成 socket.io?

有个 socket.io 的fastapi-socketio官方库,该库依赖传统的 python-socketio 库(这里请一定注意 socket.io-client.js 版本对应关系),fastapi-socketio 主要给出 fastapi 如何集成 python-socketio 的方法,省去了普通人将 python-socketio 集成到 fastapi 的工作。

代码 Demo

from fastapi import FastAPI
from fastapi_socketio import SocketManager
import uvicorn

app = FastAPI()
socket_manager = SocketManager(app=app, mount_location="/ws")

@socket_manager.on('connect',namespace="/ws")
async def connect(sid, environ):
    print(sid)
    print(environ)


if __name__ == "__main__":
    uvicorn.run(app, host="localhost", port=8888)

socket.io-client 的几个关键点

坑死你的命名空间

我们常规思维都是把 https://example.com/orders 这里的 orders 作为路径对待,可惜的是 socket.io 竟然把 host 之后的所有 path 都变成了 namespace,这是个大坑,一般人如果直接使用 host 作为 websocket 服务器一点问题都没有,但总有些情况下我们的 SSL 证书不足,我们没用二级域名,我们用了 path 来作为新的服务 endpoint,采用 nginx 进行反向代理过去,你以为会到 /orders,其实还是 https://example.com/socket.io?xxx... ,这让我百思不得其解,在多次确定服务端没有错误的情况下,我开始思考是不是 socket.io 不是这样配置的?

socket.io 命名空间用在哪里?

socket.io 原理详解 中我发现了engine.io,深入调试 socket.io 客户端源码时发现,socket.io 是建立在 engine.io 基础上针对 onmessage.data 结构设置了自己的一套协议,就叫 socket.io 协议,这个协议就有一个 namespace 的 key,这个 key 可以在 socket.io 协议层对事件进行区分,而不必新建一个 websocket,这???我还真没想到这种复用方式,也的确挺好,因此 /orders 被放到了 onmessage.data 中了,并没有在 connect 时,像 http 的方式发送给服务端了,问题来了/socket.io?xxx 这一坨参数是什么鬼?从哪里来的?

engine.io 中的 path

在 io(url, opts) 配置中,opts 有个 path 的 key,这个 key 默认就是 socket.io

虽然官方文档中也强调了,但谁能联想到?

我们再来看下服务端的默认配置

再来看看 fastapi-socketio 的源码

于是客户端的请求链接应该是这样的,是不是很惊讶?

socket = io('ws://localhost:8888/ws', {
  transports: ['websocket'],
  path:'/ws/socket.io'
});

socket.on('message', function(msg) {
    console.log(msg);
});
socket.on('reply', function(msg) {
    console.log(msg);
});

socket.io 技术选型?

因为 fastapi 主打的是异步框架,采用 asgi 的方式运行,所以python-socketio选择异步的方式进行

asgi 和 wsgi 两者的比较

以下文章讲得怪怪的,其实几句话就可以讲清楚,wsgi 是基于 python 同步语言时代产生的一种协议,按照这种协议开发出来 uwsgi 中间件可以同时满足与同步语言的应用框架下的数据交换,同时还能对外暴露接口,支持 http 协议,使得 nginx 能直接反向代理到 uwsgi,其实不用 nginx,uwsgi 本身就是个 http 协议服务器了,到了后来 async/await 这种基于事件循环的协程式语言出现,原来 wsgi 不够用了,所以就出了 asgi 协议,支持这个协议的中间件有 uvicorn 等,你说为啥需要 wsgi 协议,没有这个协议,你怎么拿到 http 协议 header 中的 Origin?

Django 3.0 ASGI 指南及其性能_Wang_AI的博客-CSDN博客

WSGI和ASGI的异同_studyeboy的博客-CSDN博客_asgi

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

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

相关文章

DSP-频域中的离散时间信号

目录 连续和离散时间傅里叶变换: 四种常用的傅立叶变换: 连续时间傅立叶变换(FT): 离散时间傅里叶变换(DTFT): 对称关系: DTFT的收敛条件: 常用DTFT对: DTFT的性质: 线性: 时间反转: 时移: 频移&#xff1a…

鲁大师2022牛角尖颁奖盛典落幕,各大硬件厂商齐聚襄阳

1月4日,鲁大师2022年度牛角尖颁奖晚会在湖北襄阳成功举办。 鲁大师的”牛角尖”奖是由过去一年上亿用户通过鲁大师测试得到的真实数据,以及鲁大师实验室通过专业的测试规范共同缔造的硬件奖项。颁发给的都是各大PC、手机、电动车领域最优秀、最顶尖的产…

【自学Python】Python HelloWorld

Windows Python HelloWorld Windows Python HelloWorld 教程 使用记事本,新建一个 helloworld.py 文件,输入以下内容: print(嗨客网(www.haicoder.net))打开命令行,进入到 helloworld.py 文件所在目录,输入以下命令…

干货 | 移动端App自动化之App控件定位

客户端的页面通过 XML 来实现 UI 的布局,页面的 UI 布局作为一个树形结构,而树叶被定义为节点。这里的节点也就对应了我们要定位的元素,节点的上级节点,定义了元素的布局结构。在 XML 布局中可以使用 XPath 进行节点的定位。App的…

Spring项目

1.创建一个Java项目 名字为Test_SM_1 2.导包 Java项目,用快捷方式的方法导入 web项目用复制的方式 一共8个包,前两个是通用jar包,Spring相关的jar包有4个,mybatis的jar包有1个,mysql的jar包连接数据库 3. 复原一个MyB…

Rabbitmq消息队列详解(一)——基础介绍

安装rabbitmq 本机: http://erlang.org.download/otp_win64_21.3.exe 一直next https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/:rabbitmq-server-3.7.14.exe 全选,next 进入RabbitMQ安装目录下的sbin目录 rabbitmq-plugins enable …

实操!用Zabbix+500元硬件如何平替5万元动环检测系统,实现UPS温湿度烟雾等数据采集存储、告警、大屏展示?

感谢本文作者 王志杰 。诚邀社区伙伴积极投稿! 前提 ►架构展示: ►大屏展示: ►所需软件: Zabbix Grafana 安装Zabbix-agent2的采集服务器 MThings串口调试软件 厂家自带UPS监控软件 USR-VCOM有人虚拟串口软件 ►所需硬件&a…

maven第二篇:IDE创建maven项目

前面将maven安装好了,当然起不会直接用,而是结合着一起用,那么现在就用IDE创建一个maven,来进行演示。 前提 IDE默认是带有maven软件,但是一般不习惯用起自带的,所以前提就是安装一个maven软件&#xff0…

HUAWEI CLOUD Stack 私有云解决方案(HCS)

HUAWEI CLOUD Stack 私有云解决(HCS) 注明: 本文介绍的版本为HUAWEI CLOUD Stack 6.5(也叫华为云Stack或HCS), 在华为6.5版本以前的名字是FusionCloud 6.3, 最近更新的8.0版本不会差别太大&…

Java开发学习(三十九)----SpringBoot整合mybatis

一、回顾Spring整合Mybatis Spring 整合 Mybatis 需要定义很多配置类 SpringConfig 配置类 导入 JdbcConfig 配置类 导入 MybatisConfig 配置类 Configuration ComponentScan("com.itheima") PropertySource("classpath:jdbc.properties") Import({JdbcC…

Trie 字典树

Trie Trie,又称字典树或前缀树。是一棵有根的多叉树。用于高效存储和查找字符串集合。 字典树从根到树上某一结点的路径就是一个字符串。 一棵字典树的构造过程图解: 字典树的度和字符集有关,英文字符集是26个字母,那么字典树的…

通用vue组件化登录页面

一、首页设置大体的样式布局 1.首先建立一个login文件夹,在里面建立对应的login.vue文件 2.设置登录页面的背景图,在App.vue文件中使用router-view进行展示登录组件 3.先给App.vue的div元素设置高度100%,之后在login.vue里面去设置背景图 …

财务管理系统|基于Springboot开发实现公司财务管理系统

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

知识库软件应该具备的7个基本功能

SaaS公司最大的业务挑战是:如何留住客户,客户与你达成合作关系后,如何让其与你继续合作,达成长期合作关系。对于SaaS产品,丢失客户的成本是很昂贵的,赢得一个新客户的成本是留住现有客户的5到25倍&#xff…

Vue脚手架的使用

一、通过命令行使用vue-cli的指令创建 1. 安装:npm i -g vue/cli-init 2. 创建Vue项目(Vue2.0项目): ​ (1)创建文件夹:vue2-demo ​ (2)进入文件夹:cd v…

[Leetcode] 相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。图示两个链表在节点 c1 开始相交:题目数据保证整个链式结构中不存在环。注意,函数返回结果后&#xf…

【 java 集合】Set 接口及常用实现类总结

📋 个人简介 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜📝 个人主页:馆主阿牛🔥🎉 支持我:点赞👍收藏⭐️留言&#x1f4d…

JavaEE【Spring】:Spring事务和事务传播机制

文章目录前言一、Spring 中事务的实现1、MySQL 中的事务使用2、Spring 编程式事务(了解)3、Spring 声明式事务(自动)① Transactional 作用范围② Transactional 参数说明③ 注意事项Ⅰ. 抛出异常Ⅱ. 手动回滚④ Transactional ⼯…

2022年亚太地区大学生数学建模竞赛/2022年亚太杯1月加赛E题思路

问题1. 基本数据分析数据集中的OWID_WRL是什么?一般是指世界world。a) 哪些国家曾经拥有过核武器?现拥有核武器的国家有9个,分别为:美国、俄罗斯、英国、法国、中国、印度、巴基斯坦、以色列,朝鲜。曾经拥有核武的国家…

【python】导入同级、下级、上级目录中的模块

不想把代码都堆到一个文件里面,希望写的分层次,但又不是web框架,有入口文件和目录规则, 这个时候就要自己分包了,会遇到这个问题,明明ide智能追踪可以定位到包引用,但是却报错module undefine&a…