Как указать экземпляры прослушивающего сервера, используя cherrypy tree.mount? - PullRequest
0 голосов
/ 24 марта 2020

Давайте создадим сервер приложений и сервер администратора. Предположим, что fusionListener и adminListener содержат логи приложения и администратора c, которые мы хотим выставить.

  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 параметры запрашивают:

  • код / ​​бизнес-логи c в качестве первого параметра
  • URL прослушивания
  • параметры конфигурации

Вот как это выглядит для вышеперечисленных серверов:

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

Но где находится параметр для сервера , который включает прослушиваемый порт ?

1 Ответ

1 голос
/ 25 марта 2020

Это не очень хорошо поддерживаемый случай для CherryPy.

Выбор приложения (cherrypy.tree - это, в основном, карта / path -> App), выполняется до отправки запроса и ... короткая история , вы могли бы использовать cherrypy.dispatch.VirtualHost и отображать ваши подчиненные приложения под основным (который будет маршрутизироваться в зависимости от имени хоста (частью которого может быть порт). Для прослушивания нескольких портов можно выполнить , но, опять же, это очень нестандартное расположение.

Я надеюсь, что этот пример иллюстрирует возможный способ сделать такое feat :

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()

Этот пример послужит AppOne при поступлении с localhost:8081 и AppTwo при поступлении с localhost:8082.

Проблема в том, что вы не можете сделать кратные cherrypy.tree.mount и ожидать маршрутизации в различные приложения, используя VirtualHost диспетчер, он предполагает, что разрешение приложения выполняется в этот момент, и только разрешает путь к этому приложению.

Сказав все это ... Я не рекомендую это решение, оно может получить Сложно, и было бы лучше иметь какой-то другой сервер впереди (например, nginx) и обслуживать каждый путь в разных процессах. Это может быть альтернативой, только если вы действительно действительно хотите избежать каких-либо дополнительных серверов или процессов в вашей настройке.

...