5

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.

Ahndwoo
  • 1,025
  • 4
  • 16
  • Add the stack trace of the error please. That will provide context that you missed to cover in the description of the problem. – Miguel Grinberg Oct 19 '19 at 11:09
  • @Miguel thanks. I've edited my question. – Ahndwoo Oct 21 '19 at 18:52
  • 1
    Strange. Do you get the same problem if you use a port number above 1024? I'm wondering if this can be related to you using a non-admin account, under which you would not be able to run anything on port 80. – Miguel Grinberg Oct 21 '19 at 22:13
  • @Miguel Maybe. I'll give it a try tomorrow. The computer ot does work on I also don't have admin privileges though, but it's worth a shot. – Ahndwoo Oct 23 '19 at 00:04
  • 1
    @Miguel Same problem using port 5000 and 8080. I do think you're on the right track about account permissions. Could also be a firewall issue? I'm also remoting in to the computer that doesn't work, but I don't see how would be an issue. – Ahndwoo Oct 23 '19 at 11:50

1 Answers1

0

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()
Muhammad Usman Bashir
  • 1,441
  • 2
  • 14
  • 43
  • Thanks for your answer, Muhammad. I don't think this is quite what i'm looking for. I'm not running `websocket.WebSocketApp`, only `websocket.Client` and `Flask-SocketIO`. The problem I'm having is that my app works as intended on one computer, but not another. I'll explore some of the resources you linked, but I'm not sure it's what I'm looking for. – Ahndwoo Oct 31 '19 at 11:47
  • Oh right, I should also mention that in my actual code, websocket.Client is running in a Celery task. I realize my example code isn't the proper way to use websocket.Client, but it's the minimum amount of code to reproduce my problem. – Ahndwoo Oct 31 '19 at 11:50
  • @Ahndwoo have you visited either of these links: `1-` https://github.com/miguelgrinberg/python-socketio/issues/223 `2-` [https://github.com/miguelgrinberg/Flask-SocketIO/issues/807] – Muhammad Usman Bashir Oct 31 '19 at 17:33
  • I've looked at the first link. The issue doesn't seem to be the same. The solution to that was substituting IP address instead of 'localhost', but that didn't do anything. The second link is broken. I also just discovered that if I remove the `transports` kwarg, I get a `Connection was refused by the server` error instead. – Ahndwoo Oct 31 '19 at 18:09
  • Ah, nevermind that's probably because the Client is in the main thread with the SocketIO app. If I make the same change to my full code, the error doesn't change. – Ahndwoo Oct 31 '19 at 18:30
  • @Ahndwoo, on new machine, try to `restart` and `update` your OS if required. Make sure: you're not confused about when you actually connect to the server and don't forget to run flask_socketio `first`, then run `websocket_client`. As on the new machine, if you have integrated the same piece of code. Then this would be due to the requirements of some `software updates` on OS. – Muhammad Usman Bashir Oct 31 '19 at 18:39