由于会话,具有gevent-socketio的多个工作人员因xhr轮询传输而失败

时间:2012-10-22 12:27:57

标签: python socket.io gevent gunicorn

我目前正尝试使用工作人员 socketio.sgunicorn.GeventSocketIOWorker 在gunicorn服务器上跨多个工作人员扩展gevent-socketio。我正在使用websockets,否则我正在强制进行XHR轮询(对于IE等)。

XHR-polling需要一个会话来跟踪以下民意调查,但是一旦我从一个到两个或更多个工作人员,请求就会开始在他们自己之间传播,这意味着状态丢失,一切都崩溃了。

我认为以下代码行是相关的: https://github.com/abourget/gevent-socketio/blob/master/socketio/handler.py#L104-106 我想我需要一些其他的存储引擎,例如我用于常规pubsub-actions的redis,但这在实际库中很深。

所以我的问题是如何在我的应用程序中全局从内存会话存储转到另一个后端引擎(它是否优雅地覆盖了上面链接中的会话代码?)没有必须修改图书馆本身? Something like PHP's session directives in php.ini。我想可以说这是一个非常通用的python问题,但我很难找到相关的信息,而且我也不确定它是否适用于这个库。

或者另外,我如何在不同的工作人员和服务器上使用gevent-socketio的xhr-polling传输(没有粘性)?

谢谢!

3 个答案:

答案 0 :(得分:3)

这显然是对socketio的限制。从我在Web上可以看到,会话处理通常在Web框架层而不是Web服务器层完成。 socketio试图在它自己的较低层上进行,并以有限的方式进行。我想作者认为一个成熟的解决方案将是一个过度杀伤力。在你的情况下,他们被证明是错误的。

只有两种方法可以克服需要逻辑更改的限制:修补源代码并在运行时修补。选择最适合你的人(或者,最好是令人厌恶的:^))。 对于第二个选项,我建议将request_tokens和/或创建它的代码替换为具有相同界面的其他实体。由于第1段中说明的原因,我真的认为socketio作者可能会接受一个源补丁,如果你提出一个补丁,它将允许它使用外部会话处理机制。

会话信息的标准位置是:共享内存,文件,数据库。我建议你改变逻辑,使socketio使用与你的web框架(或任何组成你的页面)相同的机制。

答案 1 :(得分:0)

请看这里的例子:

https://github.com/abourget/gevent-socketio/tree/master/examples/pyramid_backbone_redis_chat_persistence

它显示了如何将redis用作分布式消息队列

答案 2 :(得分:0)

只是一个想法,因为我有同样的问题;也许你可以在不同的端口上产生多个gunicorn进程,然后使用"upstream" block with "sticky" session使用nginx来平衡它们,而不是让gunicorn fork(使用-w标志)。我相信当不与Redis共享状态时,nodejs实现如何处理工作者的多处理。