当前位置:   article > 正文

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

fastapi socketio

背景

单纯的 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

  1. from fastapi import FastAPI
  2. from fastapi_socketio import SocketManager
  3. import uvicorn
  4. app = FastAPI()
  5. socket_manager = SocketManager(app=app, mount_location="/ws")
  6. @socket_manager.on('connect',namespace="/ws")
  7. async def connect(sid, environ):
  8. print(sid)
  9. print(environ)
  10. if __name__ == "__main__":
  11. 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 的源码

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

  1. socket = io('ws://localhost:8888/ws', {
  2. transports: ['websocket'],
  3. path:'/ws/socket.io'
  4. });
  5. socket.on('message', function(msg) {
  6. console.log(msg);
  7. });
  8. socket.on('reply', function(msg) {
  9. console.log(msg);
  10. });

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/863436
推荐阅读
相关标签
  

闽ICP备14008679号