Веб-сокеты Python: «Неправильное HTTP-сообщение» при попытке подключения к серверу в контейнере Docker. - PullRequest
0 голосов
/ 05 декабря 2018

В настоящее время я пишу серверное приложение, которое общается с клиентами с помощью веб-сокетов.Я хочу развернуть сервер в Docker-контейнере.Чтобы проверить соединение, я написал клиент на Python.При работе сервера без Docker в моей локальной системе клиент может без проблем подключаться, отправлять и получать сообщения.Как только я запускаю сервер в контейнере Docker, клиент не может подключиться со следующим сообщением об ошибке:

Traceback (most recent call last):   File "./client-ws.py", line 40, in <module>
    asyncio.get_event_loop().run_until_complete(loop(msg, sockaddr))   File "/usr/lib/python3.7/asyncio/base_events.py", line 573, in run_until_complete
    return future.result()   File "./client-ws.py", line 11, in loop
    async with websockets.connect(sockaddr) as sock:   File "/usr/lib/python3.7/site-packages/websockets/py35/client.py", line 2, in __aenter__
    return await self   File "/usr/lib/python3.7/site-packages/websockets/py35/client.py", line 20, in __await_impl__
    extra_headers=protocol.extra_headers,   File "/usr/lib/python3.7/site-packages/websockets/client.py", line 283, in handshake
    status_code, response_headers = yield from self.read_http_response()   File "/usr/lib/python3.7/site-packages/websockets/client.py", line 92, in read_http_response
    raise InvalidMessage("Malformed HTTP message") from exc websockets.exceptions.InvalidMessage: Malformed HTTP message

Вот код моего клиента:

async def loop(msg, sockaddr):
    async with websockets.connect(sockaddr) as sock:
        while True:
            print("Sending position {}".format(i))
            message = '{\"type\" : \"PositionUpdate\",\"position\": {\"latitude\": ' + msg[i][0] +',\"longitude\": ' + msg[i][1] + ',\"elevation\": ' + msg[i][2] + ',\"speed\": ' + msg[i][3] + '}}'
            await sock.send(message)
            print(await sock.recv())
            i += 1
            if i >= len(msg):
                i = 0
            time.sleep(1)


parser = argparse.ArgumentParser()

parser.add_argument('--host', help='The host to which the socket should bind', required=True)
parser.add_argument('--port', help='The port to which the socket should bind', required=True)
parser.add_argument('--file', help='Path to the coordinate resource file. The file should have the following structure: latitude,longitude,elevation,speed;latitude,longitude,...', required=True)
args = parser.parse_args()
file = open(args.file, 'r')
locationsStr = file.read()
locations = locationsStr.split(';')
msg = []
for l in locations:
    tmp = l.split(',')
    msg.append(tmp)
sockaddr = "ws://" + args.host + ":" + args.port

i = 0

asyncio.get_event_loop().run_until_complete(loop(msg, sockaddr))

На моем сервере, который написан на C ++, я использую библиотеку websocketpp, чтобы открыть веб-сокет.Я не могу опубликовать весь код сервера, но вот как я открываю websocket:

broadcastServer::broadcastServer(SpatMessageHandler spatHandler, MapMessageHandler mapHandler,
                                 ClearSpatCache spatCclear, ClearMapCache mapCclear) {
    this->spatHandler = spatHandler;
    this->mapHandler = mapHandler;
    this->spatCclear = spatCclear;
    this->mapCclear = mapCclear;

    m_server.init_asio();
    m_server.clear_access_channels(websocketpp::log::alevel::all);
    m_server.set_open_handler(bind(&broadcastServer::onOpen, this, ::_1));
    m_server.set_close_handler(bind(&broadcastServer::onClose, this, ::_1));
    m_server.set_message_handler(bind(&broadcastServer::onMessage, this, ::_1, ::_2));
}

...

void broadcastServer::run(uint16_t port) {
    m_server.listen(port);
    m_server.start_accept();
    m_server.run();
}

Насколько я могу судить, websocketpp связывается с 0.0.0.0 по умолчанию.Я запускаю Docker-контейнер с помощью следующей команды:

sudo docker run -p 9001:9001 -it $dockerhash

EDIT : Я только что посмотрел, что-то не так с веб-сокетом в контейнере.Выполнение netstat -an внутри контейнера показывает, что веб-сокет даже не привязан к порту.

1 Ответ

0 голосов
/ 06 декабря 2018

Проблема заключалась в том, что в моем контейнере Docker использовалась более старая версия boost, как на моей локальной машине.Я решил проблему, установив заголовки надстроек из источника.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...