Flask中的Websockets

70 投票
1 回答
57000 浏览
提问于 2025-04-18 02:59

我现在在研究Python中的websocket支持,但对可用的选项有点困惑。

一方面,可以使用Flask + gevent。另一方面,uwsgi也有socket支持,最后还有一个扩展,可以把uwsgi和gevent结合在一起。

如果只用其中一个来实现websocket,会有什么问题呢?混合使用有什么好处呢?

改变一下问题

添加gevent有什么作用,是线程版的uwsgi做不到的?

1 个回答

157

在普通的HTTP请求中,客户端和服务器之间的连接是短暂的。客户端连接到服务器,发送请求,接收响应,然后关闭连接。在这种模式下,服务器可以用少量的工作线程来服务大量的客户端。这个并发模型通常是基于线程、进程或者两者的结合。

但是,当你使用websocket时,情况就复杂了,因为websocket连接会保持很长时间,所以服务器不能用少量的工作线程来服务大量的客户端,每个客户端都需要一个专门的工作线程。如果你使用线程和/或进程,那么你的应用就无法扩展以支持大量的客户端,因为你不能有太多的线程/进程。

这时候,gevent就派上用场了。Gevent的并发模型是基于绿色线程(greenlets),这种模型比线程/进程扩展得更好。因此,使用基于gevent的服务器来处理websocket连接,可以支持更多的客户端,因为绿色线程的开销很小。使用uWSGI时,你可以选择不同的并发模型来处理websocket,包括gevent的绿色线程模型。如果你愿意,也可以单独使用gevent的web服务器。

不过要注意,gevent本身并不知道websocket,它只是一个服务器。要使用websocket连接,你需要添加一个websocket服务器的实现。

Flask有两个扩展可以简化websocket的使用。一个是由Kenneth Reitz开发的Flask-Sockets扩展,它是gevent和gevent-websocket的封装。另一个是我自己开发的Flask-SocketIO扩展,它是gevent和gevent-socketio在服务器端的封装,同时在客户端使用Socket.IO。Socket.IO是一个更高级的socket协议,可以在支持的情况下使用websocket,但也可以在旧版浏览器上使用其他传输机制。

撰写回答