В настоящее время я пишу серверное приложение, которое общается с клиентами с помощью веб-сокетов.Я хочу развернуть сервер в 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
внутри контейнера показывает, что веб-сокет даже не привязан к порту.