简体   繁体   English

使用 websocket-client 连接时出现 WinError 10057

[英]WinError 10057 when connecting using websocket-client

I'm making a Flask webapp and I'm using Flask-Socketio.我正在制作一个 Flask webapp,我正在使用 Flask-Socketio。 For various reasons, I have a need to also use the websocket-client package.由于各种原因,我还需要使用 websocket-client package。 Everything is working as intended, except that when I tried running the app on a different computer on a different network, I get the following error:一切都按预期工作,除了当我尝试在不同网络上的另一台计算机上运行该应用程序时,我收到以下错误:

"""
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
"""

I've boiled down my code as much as possible to the following, which still works on my computer, but gives the same error on the other:我已经尽可能地将我的代码归结为以下内容,它仍然可以在我的计算机上运行,但在另一个上给出了相同的错误:

|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 is just a basic 'Hello World' html page. index.html只是一个基本的“Hello World”html 页面。

What kind of stuff might give me this error on one computer/network an not another, especially just running it on localhost:80 ?什么样的东西可能会在一台计算机/网络上给我这个错误而不是另一台,尤其是在localhost:80上运行它? I really don't know what to try here.我真的不知道在这里尝试什么。

EDIT: Added traceback data to error编辑:将回溯数据添加到错误

EDIT 2: In my actual code, the websocket.Client is being run inside a Celery task.编辑 2:在我的实际代码中,websocket.Client 正在 Celery 任务中运行。 I didn't include it here because the error is reproduceable without going into that much complexity.我没有在此处包含它,因为该错误是可以重现的,而无需太复杂。

The problem is when you try to run -( Flask-webapp , websocket-client )- both of them simultaneously, only one of them will be running.问题是当您尝试同时运行 -( Flask-webapp , websocket-client )- both of them时, only one会运行。


Update:更新:

Here are some things to be noted:以下是一些需要注意的事项:

  • If you changing machine, make sure system-softwares are already up-to-date.如果您更换机器,请确保系统软件已经是最新的。
  • Check your system is not behind firewall but when you're running Flask webapp and websocket-client on the same machine then there is not need of this step.检查您的系统是否位于防火墙后面,但是当您在同一台机器上运行 Flask webapp 和 websocket-client 时,则不需要此步骤。
  • Try to restart your machine after update your OS.更新操作系统后尝试重新启动计算机。
  • Use multiprocessing instead of Threads as they won't work here because the famous Python-Global-Interpreter or GIL .使用multiprocessing而不是Threads ,因为它们在这里不起作用,因为著名的Python-Global-Interpreter 或 GIL According to which Only one thread can be in a state of execution at any point in time.根据它Only one thread can be in a state of execution at any point in time. The impact of the GIL isn't visible to developers who execute single-threaded programs, but it can be a - Performance-bottleneck - in CPU-bound and multi-threaded code.执行单线程程序的开发人员看不到 GIL 的影响,但它可能是 CPU 绑定和多线程代码中的性能瓶颈
  • Then Check: How to run flask on Port:80 .然后检查: 如何在 Port:80 上运行 flask For development purposes Port:5000 is mostly recommended. For development purposes is mostly recommended. Port:5000

  • In order to perform "Error Handling" visit the flask-socketio documentation, there is nice tips to to deal with exceptions.为了执行"Error Handling" ,请访问flask-socketio文档,有一些很好的提示来处理异常。

You can go as follow:您可以 go 如下:

@socketio.on_error_default  # handles all namespaces without an explicit error handler
def default_error_handler(e):
    pass
  • And finally, to handle socket.timeout , you may also use this following code to handle the final error: socket timed out:最后,要处理socket.timeout ,您还可以使用以下代码来处理最终错误:socket timed out:

     try: socketio.run(app,...

    except socket.error as socketerror: print("Error: ", socketerror)除了 socket.error 作为 socketerror: print("Error: ", socketerror)

  • It would be an better approach to use postman .For learning and testing purpose, try to use POSTMAN which is a quick and easy platform for sending REST , SOAP , and GraphQL requests directly within Postman. It would be an better approach to use postman learning and testing purpose, try to use POSTMAN which is a quick and easy platform for sending REST , SOAP , and GraphQL requests directly within Postman. Visit reference: getting-started-postman .访问参考: getting-started-postman

Here is an example program:这是一个示例程序:

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM