pythonflaskgunicornflask-socketio

Run a simple flask web socket on Render


I'm new to Render , and I make a simple flask web socket

I use these modules: ,flask_socketio ,flask ,gunicorn (to run my script on Render host)

Here is my code for server side:

from flask import Flask
from flask_socketio import SocketIO , emit

app = Flask("application")
socket = SocketIO(app)

@app.route("/")
def home():
    return "This is the server side !!"

@socket.on("connect")
def cl_con():
    print("A new client connected !!")

@socket.on("disconnect")
def cl_dis():
    print("A client disconnected !!")
    
@socket.on("message")
def message(data):
    emit("message",data)

if __name__ == "__main__":
    socket.run(app)

and my client side :

import socketio as io
import threading as th

name = ""

while (name == ""):
    name = input("Your name :")

def message():
    while True:
        msg = input()
        if (msg == "exit"):
            client.disconnect()
            print("Disconnected !!")
            exit(0)
        else:
            client.emit("message",f"{name}:{msg}")

client = io.Client()

client.connect("https://my_domain_name.onrender.com")
client.emit("message",f"{name} join this chat !!")

t = th.Thread(target=message)
t.daemon = True
t.start()

@client.on("message")
def msg(data):
    print(data)

client.wait()

I'm trying to connect to web socket by my client code which run on my computer , it works , but the problem is this:

1- after 10 second server side give me this error , and it continue showing this error every 5 second :

**[2025-03-07 09:05:06 +0000] [74] [CRITICAL] WORKER TIMEOUT (pid:87)
[2025-03-07 09:05:06 +0000] [87] [ERROR] Error handling request /socket.io/?transport=websocket&EIO=4&sid=E6-m_FkHPBxWcm5MAAAA&t=1741338267.3122072
Traceback (most recent call last):
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/gunicorn/workers/sync.py", line 134, in handle
    self.handle_request(listener, req, client, addr)
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/gunicorn/workers/sync.py", line 177, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask/app.py", line 1536, in __call__
    return self.wsgi_app(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/flask_socketio/__init__.py", line 42, in __call__
    return super().__call__(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/engineio/middleware.py", line 63, in __call__
    return self.engineio_app.handle_request(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/socketio/server.py", line 434, in handle_request
    return self.eio.handle_request(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/engineio/server.py", line 286, in handle_request
    packets = socket.handle_get_request(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/engineio/socket.py", line 92, in handle_get_request
    return getattr(self, '_upgrade_' + transport)(environ,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/engineio/socket.py", line 151, in _upgrade_websocket
    return ws(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/engineio/async_drivers/_websocket_wsgi.py", line 15, in __call__
    ret = self.app(self)
          ^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/engineio/socket.py", line 225, in _websocket_handler
    p = websocket_wait()
        ^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/engineio/socket.py", line 156, in websocket_wait
    data = ws.wait()
           ^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/engineio/async_drivers/_websocket_wsgi.py", line 32, in wait
    return self.ws.receive()
           ^^^^^^^^^^^^^^^^^
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/simple_websocket/ws.py", line 96, in receive
    if not self.event.wait(timeout=timeout):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/threading.py", line 629, in wait
    signaled = self._cond.wait(timeout)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/threading.py", line 327, in wait
    waiter.acquire()
  File "/opt/render/project/src/.venv/lib/python3.11/site-packages/gunicorn/workers/base.py", line 204, in handle_abort
    sys.exit(1)
SystemExit: 1**

2-when I try to connect to server by two clients , the second client get timeout error !!

any help will appreciated


Solution

  • The timeout with the second client is likely due to the fact that the default synchronous worker can only handle one request at a time. Switching to an asynchronous worker will allow multiple concurrent connections without timing out.

    Install eventlet:

    pip install eventlet

    Modify your Gunicorn command

    gunicorn -k eventlet -w 1 your_project:app

    Specify async mode in the script:

    socket = SocketIO(app, async_mode='eventlet')