2011-02-12 145 views
3

我需要创建一个Python中间件,将做到以下几点:Python的Web服务器:如何以服务请求异步

一)接受HTTP GET /来自多个客户端post请求。

b)修改并将这些请求分发到后端远程应用程序(通过套接字通信)。我无法控制这个远程应用程序。

c)从后端应用程序接收处理结果并将这些结果返回给请求客户端。

现在,客户端正在期待同步请求/响应场景。但后端应用程序不会同步返回结果。也就是说,一些请求比其他请求花费更长的时间来处理。因此,

客户端1:发送HTTP请求C1 - >得到响应R1

客户端2:发送HTTP请求C2 - >得到响应R2

客户端3:发送HTTP请求C3 - >得到响应R3

Python中间件以某种顺序接收它们:C2,C3,C1。将它们按此顺序分发到后端(作为非http消息)。后端以混合顺序R1,R3,R2响应结果。 Python中间件应该将这些响应打包回http响应对象中,并将响应发送回相关的客户端。

是否有任何示例代码来编程这种行为。似乎有20个不同的python网络框架,我很困惑,哪一个最适合这种情况(会喜欢尽可能轻量级的东西......我会认为Django太重了......我试过瓶子,但我不确定如何去编程这个场景)。

============================================== ==

更新(基于下面的讨论):请求有一个请求ID。响应有一个响应ID(它应该匹配它们对应的请求ID)。中间件和远程后端应用程序之间只有一个套接字连接。虽然我们可以维护一个{request_id:ip_address}字典,但问题是如何构建一个HTTP响应对象给正确的客户端。我认为,线程可以解决这个问题,每个线程维护自己的响应对象。

+0

您基本上需要一种方法来识别后端响应,以便您可以将其转发给正确的客户端。如果这是正确的,那么您需要进一步解释中间件后台通信是如何发生的。你是否使用每个请求的套接字或单个套接字?有什么样的信息可以用来区分回应? – jweyrich 2011-02-12 18:11:29

+0

感谢您的评论。中间件使用一个持久套接字连接到后端。所有来自中间件的请求都通过这个单一套接字转发。客户确实会发送一个请求ID和他们的请求。响应ID应该与请求ID匹配。所以问题依然存在:中间件(Web服务器)如​​何跟踪哪个请求ID属于哪个客户端?我的意思是,有没有办法让中间件中的cgi脚本创建像这样的元组的数据库,并且一旦响应id匹配,然后发送一个http响应给clientip:clienttcpport? – 2011-02-12 20:13:23

回答

2

引用您的评论:

中间件采用了单一的持久套接字连接到后端。所有来自中间件的请求都通过这个单一套接字转发。客户确实会发送一个请求ID和他们的请求。响应ID应该与请求ID匹配。所以问题依然存在:中间件(Web服务器)如​​何跟踪哪个请求ID属于哪个客户端?我的意思是,有没有办法让中间件中的cgi脚本创建一个元组数据库,并且一旦响应id匹配,然后发送一个http响应给clientip:clienttcpport?

在中间件中完成所有这些处理是否有任何特殊原因?如果更合适,你应该可以在装饰者或其他地方完成所有这些工作。

无论如何,您需要维护一个全局并行字典(扩展dict并使用threading.Lock来保护它)。在发出新请求时,将给定的请求标识存储为密钥,并将其关联到相应的客户端(发件人)。每当你的后端响应,从这个字典中检索客户端,并删除条目,使其不会永久累积。

UPDATE:有人已经为您扩展字典 - 请检查this answer

3

螺杆框架。这正是asyncore的那种任务。该模块允许基于事件的网络编程:给定一组套接字,当数据准备就绪时,它会回调给定的处理程序。这样,线程不需要只是傻傻地等待一个套接字上的数据到达并痛苦地将它传递给另一个线程。你将不得不自己实现http处理,但是可以在其中找到示例。或者,您可以使用uwsgi的异步功能,该功能可以让您的应用程序与现有的网络服务器集成,但默认情况下不与asyncore集成---尽管它不会很难使其工作。取决于具体的需求。