Django和Websockets:如何在同一个过程中创建一个包含WSGI和websockets的高效项目?

时间:2014-11-14 19:58:07

标签: django websocket twisted tornado

我试图用异步部分做一个Django应用程序:Websockets。就像一个小小的挑战,我想在同一个过程中安装所有东西。尝试过Socket.IO,但无法实际使用套接字,而不是使用longpolling(多次杀死我的浏览器,直到我放弃)。

然后我尝试了一个基于gevent-websocket的不那么维护的库。但是,有很多错误并且不容易调试。

现在我正在尝试Tornado方法,但AFAIK(请纠正我,如果我错了)将async与WSGIContainer包装的常规django应用程序集成(websockets将通过Tornado,通过Django定期连接)将是真的服务器杀手如果资源很重,或者某种程度上,Django ORM进入繁重的操作。

我正在考虑转向Twisted / Cyclone。在我从一个具有此类问题的架构迁移到另一个具有此类问题的架构之前,我想问一下:

Tornado(和/或Twisted)是否具有与Gevent相同的调度任务架构?(这意味着:当某些greenlets" block"时,他们会自行安排到其他线程,至少在操作完成之前)。我之所以这样问是因为(如果我错了,请纠正我)常规的django视图不适合像@inlineCallbacks这样的东西,并会导致整个服务器被阻止(包括的WebSockets)。

我是python中异步编程的新手,所以我有一个巨大的变化,我对多个概念有错误的信息。请在切换之前帮我澄清一下。

1 个答案:

答案 0 :(得分:3)

Tornado和Twisted都没有像gevent的魔法一样运行(某些)阻塞代码以及异步代码的性能特征。在您的应用程序中以回调和/或期货/延期形式可以看到Tornado或Twisted的惯用法。

一般情况下,由于GIL无论如何都需要运行多个python进程,所以通常最好将一些进程专门用于带有Tornado / Twisted的其他进程的webockets以及使用您选择的WSGI容器进行Django的其他进程(然后把nginx或haproxy放在前面所以它看起来像是对外界的单一服务。)

如果您仍想在同一进程中组合django和异步服务,那么下一个最佳解决方案是使用线程。如果您希望两者共享一个侦听端口,则侦听器必须是支持websocket的HTTP服务器,它可以为WSGI请求生成其他线程。 Tornado还没有解决方案,尽管计划用于4.1版(https://github.com/tornadoweb/tornado/pull/1075)。我相信Twisted的WSGI容器确实支持在线程中运行WSGI worker,但我自己没有任何经验。如果您在同一个进程中需要它们但不需要共享同一个端口,那么您只需在一个线程中运行IOLoop或Reactor,在另一个线程中运行您选择的WSGI容器(及其关联的工作线程)。