我有一个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执行相同的代码时,我无法连接到服务器。如何处理这个?
答案 0 :(得分:4)
以上两个答案都是正确的。但是,考虑到您已经实现了拼写服务器,那么将其作为一个运行。您可以首先在同一台计算机上运行它作为单独的进程 - localhost:PORT
。现在看来你已经有了一个非常简单的二进制协议接口 - 你可以在阻塞模式下使用标准的lib socket
接口实现一个同样简单的Python客户端。
但是,我建议使用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界面可以轻松地在反向代理负载平衡器后面水平扩展它。
答案 1 :(得分:3)
reactor.run()
只能在整个程序中调用一次。不要把它想象成“从我开始这一个请求”,把它想象成“开始全部扭曲”。
在后台线程中运行reactor是解决这个问题的一种方法;然后你的django应用程序可以在你的Django应用程序中使用blockingCallFromThread
并像使用任何阻塞API一样使用Twisted API。但是,您需要从WSGI容器中进行一些合作,因为您需要确保在适当的时间启动和停止此背景Twisted线程(分别初始化和拆除解释器时)。
您也可以使用Twisted作为WSGI容器,然后您不需要启动或停止任何特殊的操作; blockingCallFromThread
将立即发挥作用。请参阅twistd web --wsgi
的命令行帮助。
答案 2 :(得分:1)
在从Twisted服务器获得结果或发生某些错误/超时后,您应该停止reactor。因此,在需要查询Twisted服务器的每个Django请求中,您应该运行reactor然后停止它。但是,Twisted库不支持它 - reactor不能重启。可能的解决方案:
为Twisted reactor使用单独的线程,但是您需要使用服务器部署django应用程序,该服务器支持长时间运行的线程(我现在不用任何这些,但您可以轻松编写自己的: - 。))
不要使用Twisted来实现客户端协议,只需使用plain stdlib的socket
模块即可。