iiswebsocketsocket.ioflask-socketiowfastcgi

Flask-Socket.IO (IIS): "WebSocket is closed before the connection is established."


The Technology

The Problem

I'm experiencing issues with Flask-Socket.IO whilst running on an IIS Web Server. I'm new to WebSockets so I'm well aware that I'm probably just doing something wrong - most likely something obvious.

A Bit of Background

I've managed to successfully implement Flask-Socket.IO on my development server, and it works flawlessly every time (even running locally on the same machine as the production server). However, when I try to run it on the IIS Web Server, I just can't get it to work at all. The rest of the app runs perfectly fine, but any parts that make use of Socket.IO result in repeated calls to the WebSocket with the following error:

WebSocket connection to '<URL>' failed: WebSocket is closed before the connection is established.

...amongst a bunch of failed POST and GET requests to: <DOMAIN:PORT>/socket.io/?EIO=4&transport=polling&t=...&sid=...

What I've Tried (to no avail):

  1. Installing WebSocket Protocol for IIS (tried setting enabled to both true and false)
  2. Initialising Socket.IO with: socketio.init_app(app, cors_allowed_origins="*") (just for testing, to see if it resolved the issue) [spoiler: it didn't]
  3. Uninstalling eventlet and installing gevent instead
  4. Reading everything there is to read online
  5. Staring into the abyss of late-night confusion and wondering why I do this to myself.

The Everlasting Frustration

As you can probably tell, I'd quite like to get this one resolved now so I can move onto the next thing that invariably won't work :)

Does anybody have any suggestions? They would be much appreciated.

Thanks


Solution

  • how to deploy your flask webSocket app on IIS:

    1. code

    app.py

    from flask import Flask
    from flask_socketio import SocketIO, emit, send
    
    app = Flask(__name__)
    socketio = SocketIO(app)
    
    if __name__ == "__main__":
        socketio.run(app, host="127.0.0.1", port=8000, debug=True)
    
    @socketio.on('message')
    def handle_message(data):
        result = int(data, base=16) * 2 + 23
        send(str(hex(result)) + ' to you')
    
    

    it's a simple code for running a websocket that takes a hex number, does some math on it, and returns it as a string.

    ws_Handler.py

    from gevent import monkey
    monkey.patch_all()
    
    from app import app
    from geventwebsocket.handler import WebSocketHandler
    from gevent.pywsgi import WSGIServer
    
    http_server = WSGIServer(('127.0.0.1', 5000), app, handler_class=WebSocketHandler)
    if __name__ == '__main__':
    
        http_server.serve_forever()
    

    It's a handler that serves the app.py with gevent.

    1. IIS
    1. run code

    run ws_Handler.py on your localhost, for this just run this command on the terminal:

    python ws_Handler.py

    now your gevent server is running and you'll see this output on the terminal :

    Server initialized for event.

    now you can use your server with bonded domain on IIS.