如何使用 cherrypy tree.mount 指定监听服务器实例?
How to specify the listening server instances using cherrypy tree.mount?
让我们创建一个应用程序服务器和一个管理服务器。假设 fusionListener
和 adminListener
包含我们要公开的应用程序和管理逻辑。
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
参数要求:
- 代码/业务逻辑作为第一个参数
- 倾听url
- 配置参数
以上服务器的查找方式如下:
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)并在不同进程上为每个路径提供服务。这可能是一个替代方案,前提是您真的真的想要避免在您的设置中使用任何额外的服务器或进程。
让我们创建一个应用程序服务器和一个管理服务器。假设 fusionListener
和 adminListener
包含我们要公开的应用程序和管理逻辑。
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
参数要求:
- 代码/业务逻辑作为第一个参数
- 倾听url
- 配置参数
以上服务器的查找方式如下:
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)并在不同进程上为每个路径提供服务。这可能是一个替代方案,前提是您真的真的想要避免在您的设置中使用任何额外的服务器或进程。