WSGI¶
此示例的目的是向您展示如何使用 WSGIResource
,另一个现有的 Resource
子类,在 Twisted Web 服务器中提供 WSGI 应用程序。
请注意,WSGIResource
是一个多线程 WSGI 容器。与任何其他 WSGI 容器一样,您无法在 WSGI 应用程序中执行任何异步操作,即使这是一个 Twisted WSGI 容器。
此示例中的第一个新内容是导入 WSGIResource
from twisted.web.wsgi import WSGIResource
这里没有什么太令人惊讶的。我们仍然需要另一个常见的嫌疑人,
from twisted.internet import reactor
您很快就会明白为什么。接下来,我们需要一个 WSGI 应用程序。这是一个非常简单的应用程序,只是为了开始
def application(environ, start_response):
start_response('200 OK', [('Content-type', 'text/plain')])
return [b'Hello, world!']
如果您不理解这一点,请查看这些 优秀的教程。否则,或者完成这些教程后,下一步是创建一个 WSGIResource
实例,因为这将是另一个 rpy 脚本 示例
resource = WSGIResource(reactor, reactor.getThreadPool(), application)
让我们花点时间来仔细看看这一行。传递给 WSGIResource
的第一个参数是反应器。尽管反应器是全局的,任何想要使用它的代码都可以直接导入它(实际上,这个 rpy 脚本本身就是这么做的),但将其作为参数传递可以为将来的一些可能性打开大门——例如,拥有多个反应器。还有一些测试方面的含义。考虑一下,如果一个函数接受一个反应器(也许是一个专门构建的模拟反应器,让您的测试更容易编写),而不是导入真正的全局反应器,那么对该函数进行单元测试会容易多少。这就是为什么 WSGIResource
要求您将反应器传递给它。
传递给 WSGIResource
的第二个参数是 ThreadPool
。 WSGIResource
使用它来实际调用传递给它的应用程序对象。为了使这个示例简短,我们在这里传递了反应器的内部线程池,这样我们就可以跳过它的创建和关闭时的销毁。为了更精细地控制并行处理的 WSGI 请求数量,您可能需要创建自己的线程池来与您的 WSGIResource
一起使用,但对于简单的测试,使用反应器的线程池就可以了。
最后一个参数是应用程序对象。这在 WSGI 容器的工作方式中非常典型。
示例,不中断
from twisted.web.wsgi import WSGIResource
from twisted.internet import reactor
def application(environ, start_response):
start_response('200 OK', [('Content-type', 'text/plain')])
return [b'Hello, world!']
resource = WSGIResource(reactor, reactor.getThreadPool(), application)
在定义的 WSGIResource
实例存在于资源层次结构中的位置之前,正常的资源遍历规则适用:getChild
将被调用来处理每个段。但是,一旦遇到 WSGIResource
,这个过程就会停止,所有后续的 URL 处理都将由 WSGI 应用程序负责。但是,这个应用程序对 URL 没有任何操作,所以您无法察觉到这一点。
哦,就像第一个静态文件示例一样,您还可以使用一个命令行选项来避免很多操作。如果您只是将上面的应用程序函数(不包括所有 WSGIResource
东西)放到一个文件中,例如 foo.py
,那么您可以像这样启动一个大致等效的服务器
$ twistd -n web --wsgi foo.application