2013-12-12 1 views
0

Я использую много веб-серверов на одной машине для тестирования. Вместо того, чтобы иметь дело с конфликтами портов сервера, я хотел бы, чтобы серверы просто запрашивали ОС для доступного порта, а затем рассказывали мне, что они получили.Могу ли я получить CherryPy, чтобы найти свой собственный доступный порт?

Я могу передать порт обратно вызывающему, выполнив вход в консоль или записывая в указанный временный файл (еще не уверен), но знание номера порта является сложной частью.

В настоящее время на основе сервер WSGI вводится в действие с:

cherrypy.quickstart(dev_server, config=_GetConfig(options)) 

Конфиг будет содержать следующее:

{ 'global': 
        { <snip> 
        'server.socket_host': '0.0.0.0', 
        'server.socket_port': int(options.port) 
        }, 
    <snip> 
} 

Есть ли способ сделать это с CherryPy?

Я предполагаю, что я могу установить порт на «0», чтобы он был автоматически выбран, но это не дает мне способ сообщить об этом.

+1

Как вы хотите, чтобы они рассказали вам, что они получили? Печать на консоль? Войдите в syslog? Записать его в файл запуска? Подключиться к некоторому главному серверу и отправить его через некоторый API? – abarnert

+0

Есть ли много веб-серверов, конкурирующих за порт? Цикл, который пробует порт случайно, найдет один после нескольких раундов. Но не думайте об этом цикле, прежде чем вы получите ответ на комментарий @abarnert. – ixe013

+0

Также расскажите, как вы запускаете сервер (ы) и как их настраиваете, потому что у CherryPy много гибкости. – abarnert

ответ

3

Основная идея:

  • Привязать к порту 0.
  • Ask сокет, какой порт вы в конечном итоге с.
  • Сообщите об этом порту как-то.

Первая часть сильно зависит от того, как вы строите, запускаете и настраиваете свои серверы. CherryPy чрезвычайно гибкий, и детали будут отличаться в зависимости от того, как вы его используете.

Вторая часть требует, чтобы вы использовали какой-либо механизм, в котором вы пишете код верхнего уровня, который запускает серверы, и не один из механизмов, который запускает их автоматически без какого-либо кода. Это связано с тем, что перед запуском сервера вам потребуется вручную bind сервер, чтобы получить его сокет. После того, как у вас есть созданный и связанный сокет, getsockname предоставит вам адрес и порт, с которыми он связан.

Третья часть, очевидно, может быть такой же простой или сложной, как вы хотите.


Вот простой пример, который вы можете сделать даже из интерактивного интерпретатора:

def app(env, start): 
    start('200 OK', [('Content-type', 'text/plain')]) 
    return ['Hello, world!'] 
server = cherrypy.wsgiserver.CherryPyWSGIServer(('0.0.0.0', 0), app, 
               server_name='localhost') 
server.bind(socket.AF_INET, socket.SOCK_STREAM) 
addr, port = server.socket.getsockname() 
print(port) 
server.start() 

Вы также можете взглянуть на cherrypy.process.servers и ее ServerAdapter, который позволяет управлять несколько серверов из одного места, вместо того, чтобы иметь кучу независимых серверов, которые вы должны вручную координировать.

+0

Иногда я чувствую, что мы просто «отдаем» решения проблем «слишком легко». Хороший ответ, однако :) –

+0

@JamesMills: Это только отдает решение, если он использует плоский «CherryPyWSGIServer» со всей конфигурацией, жестко закодированной в источнике, и я действительно сомневаюсь, что он использует. Я надеюсь, что ему достаточно понять, как адаптироваться к тому, что он на самом деле делает, и/или найти соответствующую информацию в документах, и/или по крайней мере задать лучший вопрос ... – abarnert

+0

* sigh * :) Я делаю признайте это, хотя, вы ответили/были лучше сформулированы и ожесточены, чем мои были :) –