Python / JavaScript - проблема с подключением к WebSockets - PullRequest
3 голосов
/ 09 июля 2020

У меня есть несколько ошибок с сервером WebSockets .

Раньше у меня было много проблем с подтверждением сервера при установке соединения. В адресе привязки у меня есть пустая строка, равная 0.0.0.0, поэтому я подумал, что проблема может исходить оттуда. На данный момент клиент может знать, что он был подключен, только когда сервер останавливает функцию time asyn c. Иногда я получаю сообщение об ошибке

send.html:14 WebSocket connection to ws://86.205.245.32:5678/ failed: WebSocket opening handshake timed out

, но редко.

У меня много вопросов, на которые можно ответить на этот пост.

  • Можно ли воспользоваться справкой по подпротоколу? Если да, то как использовать его с сервером Python?

  • Можно ли использовать справку WSS?

  • Нужно ли менять привязку IP 0.0.0.0 другому?

Сервер

print("start serveur")
import time, websockets, asyncio

async def time(websocket, path):
    print("connect")
    print(websocket)
    print(await websocket.recv())
start_server = websockets.serve(time, "", 5678)
loop=asyncio.get_event_loop() 

loop.run_until_complete(start_server)


loop.run_forever()

Сервер Traceback

Error in connection handler
Traceback (most recent call last):
  File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
    result = coro.throw(exc)
  File "/usr/local/lib/python3.5/dist-packages/websockets/protocol.py", line 674, in transfer_data
    message = yield from self.read_message()
  File "/usr/local/lib/python3.5/dist-packages/websockets/protocol.py", line 742, in read_message
    frame = yield from self.read_data_frame(max_size=self.max_size)
  File "/usr/local/lib/python3.5/dist-packages/websockets/protocol.py", line 815, in read_data_frame
    frame = yield from self.read_frame(max_size)
  File "/usr/local/lib/python3.5/dist-packages/websockets/protocol.py", line 884, in read_frame
    extensions=self.extensions,
  File "/usr/local/lib/python3.5/dist-packages/websockets/framing.py", line 99, in read
    data = yield from reader(2)
  File "/usr/lib/python3.5/asyncio/streams.py", line 668, in readexactly
    yield from self._wait_for_data('readexactly')
  File "/usr/lib/python3.5/asyncio/streams.py", line 458, in _wait_for_data
    yield from self._waiter
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 285, in result
    raise CancelledError
concurrent.futures._base.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/websockets/server.py", line 169, in handler
    yield from self.ws_handler(self, path)
  File "webserveur.py", line 8, in time
    print(await websocket.recv())
  File "/usr/local/lib/python3.5/dist-packages/websockets/protocol.py", line 434, in recv
    yield from self.ensure_open()
  File "/usr/local/lib/python3.5/dist-packages/websockets/protocol.py", line 658, in ensure_open
    ) from self.transfer_data_exc
websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1006 (connection closed abnormally [internal]), no reason

Клиент

<script>
    alert("hello");

    var ws = new WebSocket("ws://86.205.245.32:5678/"  );//1*
        
    ws.onopen = function (event) {
       alert("had a handshake answer that cause a connection");
       ws.send("hello");
    }

</script>

Запрос WebSockets

General
Request URL: ws://86.205.245.32:5678/
Request Headers
Provisional headers are shown
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,fr;q=0.7
Cache-Control: no-cache
Connection: Upgrade
Host: 86.205.245.32:5678
Origin: file://
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: M+CfTACesBfbhkWnFclrsA==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

Я хочу использовать DMZ , потому что моя сеть очень странная с большой степенью защиты, поэтому я думаю, что установка сервера в Демилитаризовать зону поможет. На данный момент я не могу сказать вам, будет ли это полезно, потому что на данный момент, когда клиент выполняет строку 1* see on the client code, он не может подключиться к серверу. Странно то, что без DMZ и сервера на компьютере Windows это то же самое, но для отправки данных клиент может видеть данные сервера только тогда, когда сервер закрывает соединение.

Что я пробовал

  • Я пытался отключить брандмауэр
  • Я задавал вопросы в StackOverflow

У меня часто возникают эти проблемы, когда я закрываю сервер во время выполнения клиента, даже если он не выполняет блок time, который печатает print("connect"):

Task was destroyed but it is pending!
task: <Task pending coro=<WebSocketServerProtocol.handler() running at /usr/local/lib/python3.5/dist-packages/websockets/server.py:117> wait_for=<Future pending cb=[Task._wakeup()]>>

Я также изменил код клиента следующим образом, но безуспешно.

var ws = new WebSocket("ws://86.205.245.32:5678/"),
        messages = document.createElement('ul');

        ws.onopen = function (event) {
        alert("connect");
        ws.send("hello");
        
        }

Аппаратное обеспечение

  • A Windows компьютер (клиент)

  • Rasberry Pi (сервер)

Спасибо за помощь и дайте мне знать, если вы эта проблема уже была и что вы сделали для ее решения. Или, если вы обнаружили ошибки в коде, которые могут вызвать проблемы такого типа

СПАСИБО

1 Ответ

0 голосов
/ 14 июля 2020

Я попытался воспроизвести вашу проблему, но я считаю, что ваша проблема вызвана вашей сетевой инфраструктурой.

Сервер и client очень просты c, и они работают без сбоев.

Разделите проблему на разные фазы:

  1. Используйте локальную среду для отладки кода ( клиент и сервер в localhost, на вашем P C)
  2. Используйте свою локальную сеть для первого разделения между клиентом и сервер
  3. Воспользуйтесь некоторыми бесплатными планами облачных провайдеров для тестирования расширенной сети (AWS, GCP, DigitalOcean)

Некоторые предложения могут быть :

  • Полностью отключить Windows брандмауэр
  • Убедитесь, что у вас нет брандмауэров на вашем Linux Distro (UFW, IPTables ...)
  • Используйте LAN IP вашего Raspberry Pi для тестирования вместо его publi c IP
  • Убедитесь, что в вашем Livebox Играйте , у вас нет брандмауэра или некоторых правил маршрутизации
...