2

我有一个 Django 网络应用程序。我还有一个使用 twisted 编写的拼写服务器,运行在具有 django 的同一台机器上(运行在 django 上localhost:8090)。这个想法是当用户执行某些操作时,请求来到 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 执行相同的代码时,我无法连接到服务器。如何处理这个?

4

3 回答 3

4

以上两个答案都是正确的。但是,考虑到您已经实现了一个拼写服务器,然后将其作为一个. 您可以首先在同一台机器上作为单独的进程运行它 - 在localhost:PORT. 现在看来你已经有了一个非常简单的二进制协议接口——你可以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 界面也可以轻松地在反向代理负载均衡器后面横向扩展它。

于 2011-01-16T15:35:31.350 回答
3

reactor.run()在整个程序中应该只调用一次。不要把它想象成“开始我的这个请求”,把它想象成“开始所有的 Twisted”。

在后台线程中运行反应器是解决此问题的一种方法;那么您的 django 应用程序可以blockingCallFromThread在您的 Django 应用程序中使用,并像使用任何阻塞 API 一样使用 Twisted API。不过,您将需要 WSGI 容器的一点合作,因为您需要确保这个后台 Twisted 线程在适当的时间启动和停止(分别在您的解释器被初始化和拆除时)。

你也可以使用 Twisted 作为你的 WSGI 容器,然后你不需要启动或停止任何特殊的东西;blockingCallFromThread将立即工作。请参阅 的命令行帮助twistd web --wsgi

于 2010-12-27T03:37:48.293 回答
1

从 Twisted 服务器获得结果或发生一些错误/超时后,您应该停止反应器。因此,对于需要查询 Twisted 服务器的每个 Django 请求,您应该运行 reactor 然后停止它。但是,Twisted 库不支持它——reactor 不可重新启动。可能的解决方案:

  • 为 Twisted reactor 使用单独的线程,但您需要使用服务器部署 django 应用程序,该服务器支持长时间运行的线程(我现在不支持这些线程,但您可以轻松编写自己的 :-))。

  • 不要使用 Twisted 来实现客户端协议,只需使用普通的 stdlibsocket模块。

于 2010-12-26T20:11:00.967 回答