WinError 10057 при подключении с помощью websocket-клиента - PullRequest
3 голосов
/ 18 октября 2019

Я делаю веб-приложение Flask и использую Flask-Socketio. По разным причинам мне необходимо также использовать пакет websocket-client. Все работает так, как задумано, за исключением того, что, когда я пытался запустить приложение на другом компьютере в другой сети, я получаю следующую ошибку:

"""
Traceback (most recent call last):
  File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 2449, in wsgi_app
    response = self.handle_exception(e)
  File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1866, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "[Path to venv]\venv\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "[Path to venv]\venv\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "[Path to venv]\venv\lib\site-packages\flask\app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "[Path to app]\app\views.py", line 7, in index
    sio.connect("http://localhost:80/", transports=['websocket', 'polling'])
  File "[Path to venv]\venv\lib\site-packages\socketio\client.py", line 262, in connect
    engineio_path=socketio_path)
  File "[Path to venv]\venv\lib\site-packages\engineio\client.py", line 170, in connect
    url, headers, engineio_path)
  File "[Path to venv]\venv\lib\site-packages\engineio\client.py", line 346, in _connect_websocket
    cookie=cookies)
  File "[Path to venv]\venv\lib\site-packages\websocket\_core.py", line 514, in create_connection
    websock.connect(url, **options)
  File "[Path to venv]\venv\lib\site-packages\websocket\_core.py", line 223, in connect
    options.pop('socket', None))
  File "[Path to venv]\venv\lib\site-packages\websocket\_http.py", line 120, in connect
    sock = _open_socket(addrinfo_list, options.sockopt, options.timeout)
  File "[Path to venv]\venv\lib\site-packages\websocket\_http.py", line 189, in _open_socket
    raise error
  File "[Path to venv]\venv\lib\site-packages\websocket\_http.py", line 172, in _open_socket
    sock.connect(address)
OSError: [WinError 10057] A request to send or receive data was disallowed because 
the socket is not connected and (when sending on a datagram socket using a sendto call) 
no address was supplied
"""

Я как можно больше сварил свой код, чтобыследующее, которое все еще работает на моем компьютере, но выдает ту же ошибку на другом:

|start.py
|app
    |__init__.py
    |views.py
    |templates
        |index.html
# __init__.py

from flask import Flask
from flask_socketio import SocketIO
from gevent import monkey

monkey.patch_all()

APP = Flask(__name__)
SOCKETIO = SocketIO(APP, engineio_logger=True, logger=True)

from . import views
# views.py

from app import APP
from socketio import Client
from flask import render_template

@APP.route('/', methods=['GET', 'POST'])
def index():
    sio = Client()
    sio.connect("http://localhost:80", transports=['websocket', 'polling']) # Error being caused here
    return render_template('index.html')
# start.py

from app import APP, SOCKETIO

if __name__ == "__main__":
    SOCKETIO.run(APP, debug=True, port=80, host='0.0.0.0')

index.html - это просто базовая HTML-страница «Hello World»,

Какие вещи могут вызывать эту ошибку на одном компьютере / сети, а не на другом, особенно если запустить ее на localhost:80? Я действительно не знаю, что здесь попробовать.

РЕДАКТИРОВАТЬ: добавлены данные трассировки к ошибке

РЕДАКТИРОВАТЬ 2: В моем реальном коде websocket.Client запускается внутри задачи Celery. Я не включил это здесь, потому что ошибка воспроизводима, не вдаваясь в такую ​​сложность.

1 Ответ

3 голосов
/ 30 октября 2019

Проблема заключается в том, что при попытке запустить - ( Flask-webapp , websocket-client ) - both of them одновременно, only one из них будет запущено.


Обновление:

Вот несколько моментов, на которые следует обратить внимание:

  • Если вы меняете машину, убедитесь, что системное программное обеспечение уже установлено. в актуальном состоянии.
  • Убедитесь, что ваша система не защищена брандмауэром, но когда вы запускаете Flask webapp и websocket-client на одном компьютере, этот шаг не требуется.
  • Попробуйте перезагрузить компьютер после обновления ОС.
  • Используйте multiprocessing вместо Threads, так как они не будут работать здесь из-за известного Python-Global-Interpreter или GIL . В соответствии с этим Only one thread can be in a state of execution at any point in time. Влияние GIL не заметно разработчикам, выполняющим однопоточные программы, но это может быть - Узкое место в производительности - в многопоточных кодах, связанных с ЦП.
  • Затем проверьте: Как запустить колбу на порту: 80 . For development purposes Порт: 5000 is mostly recommended.

  • Для выполнения "Error Handling" посетите документацию колба , есть хорошаяСоветы по работе с исключениями.

Можно поступить следующим образом:

@socketio.on_error_default  # handles all namespaces without an explicit error handler
def default_error_handler(e):
    pass
  • И, наконец, справиться с socket.timeout, выможет также использовать следующий код для обработки окончательной ошибки: время ожидания сокета:

    try:
    socketio.run(app,...
    

    , за исключением socket.error как socketerror: print ("Ошибка:", socketerror)

  • Было бы лучше использовать цель postman. Для learning and testing, попробуйте использовать POSTMAN, которая является быстрой и простой платформой для прямой отправки REST, SOAP и GraphQL запросов. в пределах почтальона. Ссылка для посещения: начинающий почтальон .

Вот пример программы:

import multiprocessing

# Assume for flask-app
def start_flask_app:
    app.run()

# Assume for websocket-client-app
# Assume basic events you will handle in your client e.g. on_message, on_error, on_close
def start_ws:
    ws = websocket.WebSocketApp(WS_URI, on_message= on_message,
                                        on_error = on_error, 
                                        on_close = on_close)
    ws.on_open = on_open
    ws.run_forever()

# use of sub-processes instead of threads.
p_flask = multiprocessing.Process(target=start_flask_app)
p_ws = multiprocessing.Process(target=start_ws)

p_ws.start()
p_flask.start()

p_ws.join()
p_flask.join()
...