Python,Twisted,Django,Reactor.run()引起问题
-
13-10-2019 - |
题
我有一个Django Web应用程序。我还使用django上的同一台计算机上写的扭曲运行(运行) localhost:8090
)。这个想法是当用户采取某些操作时,请求提交Django,而Django又连接到此扭曲的服务器和服务器将数据发送回Django。最后,Django将这些数据放入一些HTML模板中,并将其提供给用户。
这是我遇到问题的地方。在我的Django应用程序中,当请求进来时,我创建了一个简单的扭曲客户端,以连接到本地运行的扭曲服务器。
...
factory = Spell_Factory(query)
reactor.connectTCP(AS_SERVER_HOST, AS_SERVER_PORT, factory)
reactor.run(installSignalHandlers=0)
print factory.results
...
这 reactor.run()
正在引起问题。因为这是事件循环。下次Django执行相同的代码时,我无法连接到服务器。一个人如何处理?
解决方案
以上两个答案是正确的。但是,考虑到您已经实施了拼写 服务器 然后 将其作为一个. 。您可以从与单独的过程在同一机器上运行它 - at localhost:PORT
. 。现在看来您已经有一个非常简单的二进制协议接口 - 您可以使用标准LIB实现同样简单的Python客户端 socket
接口处于阻塞模式。
但是,我建议和 twisted.web
并公开一个简单的Web界面。您可以使用JSON来序列化和估算数据 - Django很好地支持了数据。这是一个非常快的示例:
import json
from twisted.web import server, resource
from twisted.python import log
class Root(resource.Resource):
def getChild(self, path, request):
# represents / on your web interface
return self
class WebInterface(resource.Resource):
isLeaf = True
def render_GET(self, request):
log.msg('GOT a GET request.')
# read request.args if you need to process query args
# ... call some internal service and get output ...
return json.dumps(output)
class SpellingSite(server.Site):
def __init__(self, *args, **kwargs):
self.root = Root()
server.Site.__init__(self, self.root, **kwargs)
self.root.putChild('spell', WebInterface())
为了运行它,您可以使用以下骨架 .tac
文件:
from twisted.application import service, internet
site = SpellingSite()
application = service.Application('WebSpell')
# attach the service to its parent application
service_collection = service.IServiceCollection(application)
internet.TCPServer(PORT, site).setServiceParent(service_collection)
如果您发现需要,则运行服务作为另一类服务,您可以在另一台计算机上运行它 - 曝光Web界面使得可以轻松地在反向代理负载平衡器后面水平缩放它。
其他提示
reactor.run()
在整个程序中应仅调用一次。不要将其视为“开始我有一个请求”,而是将其视为“启动所有扭曲”。
在背景线程中运行反应堆是解决此问题的一种方法。然后您的Django应用程序可以使用 blockingCallFromThread
在您的Django应用程序中,并使用扭曲的API,就像任何阻止API一样。但是,您需要从WSGI容器中进行一些合作,因为您需要确保在适当的时间启动并停止此背景扭曲的线程(分别初始化和拆除时)。
您也可以将Twisted用作WSGI容器,然后您无需启动或停止任何特别的东西; blockingCallFromThread
将立即工作。查看命令行的帮助 twistd web --wsgi
.
在获得扭曲服务器的结果或某些错误/超时发生后,您应该停止反应堆。因此,在每个需要查询您的扭曲服务器的Django请求时,您应该运行反应堆,然后停止。但是,它不受扭曲库的支持 - 反应堆无法重新启动。可能的解决方案:
使用单独的线程进行扭曲反应堆,但是您需要使用服务器部署Django应用程序,该应用程序支持长期运行的线程(我现在没有任何这些,但是您可以轻松地编写自己的内容:-))。
不要使用扭曲来实现客户端协议,只需使用普通的stdlib
socket
模块。