Получить агента VOLTTRON для ответа на запросы http
Мне трудно собрать все воедино, чтобы агент отвечал на запросы http. Я видел этот ответ от Крейга Добавить новую страницу в Volttron Central, но все еще не уверен, как все это собрать. Надеюсь, этот вопрос может послужить учебным пособием или, по крайней мере, местом для указания на конкретное место в документации.
С этой целью вот простейшее изложение моего вопроса:
Скажем, у меня установлена версия VOLTTRON по умолчанию в Ubuntu с помощью bootstrap.py. Я нахожусь в ветке разработки, так как именно на это указывает ответ на вопрос выше, если это не правильно, или другие ветки также имеют эту функциональность, пожалуйста, укажите.
И скажи, что у меня есть следующий код агента
class Hello_Internet(Agent):
def hello_internet(self):
return “Hello Internet”
Что должно произойти, чтобы иметь возможность отправлять запрос на URL-адрес в форме "что-то / hello_internet" и получать ответ "Hello Internet" через метод агента HelloInternet? А что такое "что-то" в URL? Бонусные баллы за получение типа запроса и другой связанной информации (строка запроса, тело запроса после отправки).
В духе демонстрации того, что я уже попробовал, надеюсь, что следующее не сильно замурует воду. В идеале вы просто скажете, что я полностью потерял сюжет, и тогда мы сможем отредактировать нижеследующее.
Я начал с добавления флага –bind-web-address " http://127.0.0.1:5555/" к параметрам при запуске самой платформы.
Затем я обновил свой класс агента до
class Hello_Internet(Agent):
@RPC.export
def hello_internet(self):
return "Hello Internet"
@Core.receiver('onstart')
def on_message_bus_start(self, sender, **kwargs):
self.vip.rpc.call(MASTER_WEB, 'register_agent_route',
r'^/hello_internet',
self.core.identity,
"hello_internet").get(timeout=30)
В этот момент, когда я запускаю платформу, она записывает это при запуске:
volttron.platform.web INFO: Starting web server binding to 127.0.0.1:5555.
И это, когда агент начинает:
volttron.platform.web INFO: Registering agent route expression: ^/hello_internet peer: None function: hello_internet
Но если я на самом деле перехожу к 127.0.0.1:5555, то платформа выдает эту ошибку в отладчике:
“~/workspace/volttron/env/local/lib/python2.7/site-packages/gevent/server.py", line 102, in wrap_socket_and_handle
ssl_socket = self.wrap_socket(client_socket, **self.ssl_args)
TypeError: wrap_socket() got an unexpected keyword argument 'error_log'
<Greenlet at 0x7f9ea46e7e10: <bound method WSGIServer.wrap_socket_and_handle of <WSGIServer at 0x7f9ea46cba90 fileno=58 address=127.0.0.1:5555>>(<socket at 0x7f9ea46cb9d0 fileno=61 sock=127.0.0.1, ('127.0.0.1', 40583))> failed with TypeError
Для чего стоит self.ssl_agrs в приведенном выше
dict: {'error_log': <open file '~/.volttron/log/web.error.log', mode 'wb' at 0x7f9ea5a2c5d0>,
'server_side': True}
Файл ~/.volttron/log/web.error.log существует, но он пуст.
Это происходит до вызова функции hello_internet.
Я попытался обновить Gevent, и это не решило проблему. Я попытался переключить –bind-web-address на https://127.0.0.1:5555/ и перейти туда, а также несколько других вещей, которые только запутывают, я думаю, но пока что безуспешно.
РЕДАКТИРОВАТЬ
Спасибо за ваш быстрый ответ. Я обновил свои библиотеки, чтобы они соответствовали списку пипсов Крэйга ниже. В некоторых случаях я мог обновиться до более новой версии библиотеки, такой как gevent 1.1.2 вместо 1.1.1. Я также изменил сигнатуру функции hello_internet в соответствии с предложением Крейга и изменил связанный адрес с https на http.
Теперь, когда я запускаю платформу и агент и пытаюсь перейти к связанному ip, я получаю "Внутреннюю ошибку сервера" из браузера, и платформа дает следующую трассировку:
~/workspace/volttron/env/local/lib/python2.7/site-packages/zmq/sugar/socket.py", line 363, in send_multipart
i, rmsg,
TypeError: Frame 0 (None) does not support the buffer interface.
{'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.5',
'HTTP_CONNECTION': 'keep-alive',
'HTTP_HOST': '127.0.0.1:5555',
'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0',
'PATH_INFO': '/hello_internet',
'QUERY_STRING': '',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '40704',
'REQUEST_METHOD': 'GET',
'SCRIPT_NAME': '',
'SERVER_NAME': 'localhost',
'SERVER_PORT': '5555',
'SERVER_PROTOCOL': 'HTTP/1.1',
'SERVER_SOFTWARE': 'gevent/1.1 Python/2.7',
'wsgi.errors': <open file '/home/bob/.volttron/log/web.error.log', mode 'wb' at 0x7f77dc4386f0>,
'wsgi.input': <gevent.pywsgi.Input object at 0x7f77dc341e20>,
'wsgi.multiprocess': False,
'wsgi.multithread': False,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http',
'wsgi.version': (1, 0)} failed with TypeError
1 ответ
Из того, что я вижу, единственная проблема, которую я вижу, состоит в том, что обратный вызов (метод, к которому MASTER_WEB направляет, должен иметь функцию как
class Hello_Internet(Agent):
@RPC.export
def hello_internet(self, env, data):
return "Hello Internet"
Кроме того, эта ошибка не должна быть проблемой, если у вас установлен Gevent 1.1.1. По крайней мере, это версия, которую я использую.
Пожалуйста, сравните мой список с вашим
avro (1.8.1)
bacpypes (0.13.2)
configobj (5.0.6)
docutils (0.12)
funcsigs (1.0.2)
gevent (1.1.1)
gprof2dot (2015.12.1)
greenlet (0.4.9)
mock (2.0.0)
monotonic (1.1)
pbr (1.10.0)
pip (8.1.2)
ply (3.8)
psutil (4.3.0)
py (1.4.31)
pymodbus (1.2.0)
pymongo (3.3.0)
pyserial (3.1)
pytest (2.9.2)
pytest-profiling (1.1.1)
python-dateutil (2.5.3)
pytz (2016.4)
pyzmq (14.7.0)
requests (2.10.0)
setuptools (22.0.5)
simplejson (3.8.2)
six (1.10.0)
Smap (2.0.24c780d)
Twisted (16.2.0)
volttron (3.5.0, /home/vdev/git/volttron)
wheel (0.29.0)
zope.interface (4.1.3)