Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WinError 10057 when connecting using websocket-client

I'm making a Flask webapp and I'm using Flask-Socketio. For various reasons, I have a need to also use the 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.

What kind of stuff might give me this error on one computer/network an not another, especially just running it on 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. I didn't include it here because the error is reproduceable without going into that much complexity.

like image 449
Ahndwoo Avatar asked Nov 06 '22 13:11

Ahndwoo


1 Answers

The problem is when you try to run -(Flask-webapp, websocket-client)- both of them simultaneously, only one of them will be running.


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.
  • 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. According to which 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.
  • Then Check: How to run flask on Port:80. For development purposes Port:5000 is mostly recommended.

  • In order to perform "Error Handling" visit the flask-socketio documentation, there is nice tips to to deal with exceptions.

You can go as follow:

@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:

    try:
    socketio.run(app,...
    

    except socket.error as 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. Visit reference: 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()
like image 124
Muhammad Usman Bashir Avatar answered Nov 15 '22 10:11

Muhammad Usman Bashir