如何使用 cherrypy tree.mount 指定监听服务器实例?

How to specify the listening server instances using cherrypy tree.mount?

让我们创建一个应用程序服务器和一个管理服务器。假设 fusionListeneradminListener 包含我们要公开的应用程序和管理逻辑。

  from cherrypy._cpserver import Server
  fserver = Server()
  fserver.socket_port = 10000
  fserver.subscribe()

  aserver = Server()
  aserver.socket_port = 10001
  aserver.subscribe()

然后启动它们:

cherrypy.engine.start()
cherrypy.engine.block()

tree.mount参数要求:

以上服务器的查找方式如下:

  cherrypy.tree.mount(fusionListener, r"/fusion.*",fusionConf)
  cherrypy.tree.mount(adminListener, r"/admin.*",adminConf)

但是 server 本身的参数在哪里 - 其中包括被监听的 port

这不是 CherryPy 的良好支持案例。

应用程序选择(cherrypy.tree 基本上是 /path -> App 的映射)在请求发送之前完成,并且...长话短说,您 可以 使用 cherrypy.dispatch.VirtualHost 并将您的子应用程序映射到主应用程序下(这将根据主机名(端口可以是其中的一部分)进行路由)。对于多个端口的侦听,可以完成,但这又是一个非常定制的安排。

我希望这个例子能够说明实现这种 壮举:

的可能方法
import cherrypy

from cherrypy import dispatch
from cherrypy._cpserver import Server


class AppOne:

    @cherrypy.expose
    def default(self):
        return "DEFAULT from app ONE!"

    @cherrypy.expose
    def foo(self):
        return "FOO from app ONE"


class AppTwo:

    @cherrypy.expose
    def default(self):
        return "DEFAULT from app TWO!"

    @cherrypy.expose
    def foo(self):
        return "FOO from app TWO"


class Root:

    def __init__(self):
        self.one = AppOne()
        self.two = AppTwo()


def bind_two_servers(app_one_port, app_two_port):
    # unsubscribe the default server
    cherrypy.server.unsubscribe()
    s1 = Server()
    s2 = Server()
    s1.socket_port = app_one_port
    s2.socket_port = app_two_port
    # subscribe the server to the `cherrypy.engine` bus events
    s1.subscribe()
    s2.subscribe()


def start_server():
    bind_two_servers(8081, 8082)
    cherrypy.engine.signals.subscribe()
    cherrypy.engine.start()
    cherrypy.engine.block()


config = {
    '/': {
        'request.dispatch': dispatch.VirtualHost(**{
            'localhost:8081': '/one',
            'localhost:8082': '/two',
        })
    }
}

cherrypy.tree.mount(Root(), '/', config)
start_server()

此示例将在来自 localhost:8081 时提供给 AppOne,在来自 localhost:8082 时提供给 AppTwo

问题是您不能执行多个 cherrypy.tree.mount 并期望使用 VirtualHost 调度程序路由到不同的应用程序,它假定应用程序解析已在该点完成并且是仅解析该应用程序的路径。

说了这么多......我不推荐这个解决方案,它会变得复杂,最好在前面有一些其他服务器(如 nginx)并在不同进程上为每个路径提供服务。这可能是一个替代方案,前提是您真的真的想要避免在您的设置中使用任何额外的服务器或进程。