Home > other >  How to end Flask SocketIO with Crtl C, Error 403 (Forbidden)
How to end Flask SocketIO with Crtl C, Error 403 (Forbidden)

Time:12-28

How do I end socket gracefully? I tried using signal.SIGINT but no success.

Is there another way? I'm running in development and can't seem to stop socket after Crtl C. Browser console log continues to print and locks the browser from reloading the page when app.py starts up again.

enter image description here

Here is my app.py

from logging.handlers import SocketHandler
import os
import pandas as pd
import json
import threading
import signal
from flask import Flask, render_template, session, request, jsonify

from flask_socketio import SocketIO
from flask_cors import CORS, cross_origin

app = Flask(__name__)
app.debug = True
socketio = SocketIO(
    app, cors_allowed_origins="*", always_connect=True, async_mode="threading"
)

app.config["SECRET_KEY"] = "secret!"


def signal_handler(signum, frame):
    exit_event.set()
    SocketHandler.close(socketio)


exit_event = threading.Event()


@socketio.on("response_demo")
def background_task_func():
    """Example of how to send server generated events to clients."""
    i = 0

    while True:
        if exit_event.is_set():
            print(f"completed {threading.current_thread().name} : {os.getpid()} ")
            socketio.disconnect()
            socketio.settimeout(2)
            socketio.close()
            # SocketHandler.close(socketio)
            break
        socketio.sleep(5.05)
        data = {
            "Name": "data packet",
            "p": [{"x": i, "a": 12, "b": 12, "c": 10, "d": 10, "e": 10}],
        }
        data_2 = pd.DataFrame(data)
        df_json = data_2.to_json(orient="records")
        result = {"objects": json.loads(df_json)}
        socketio.emit("my_response", result, broadcast=True)


@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "GET":
        return render_template("index-so.html")

    exit_event.clear()
    val = request.json.get("c_check")
    bg = threading.Thread(target=background_task_func, daemon=True)

    if val == 1:
        # bg.start()
        print(f"c_check = 1")
    elif val == 0:
        try:
            print("trying to kill thread")
            exit_event.set()
        except Exception as e:
            print(e)
        print("val0 is ", val)
    response = jsonify({"data": {"val": val}})
    return response


if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal_handler)
    socketio.run(
        app, logger=True, engineio_logger=True, use_reloader=True, debug=True, port=5000
    )

CodePudding user response:

The Ctrl-C stops the server. The errors that you see are from the client, which runs in the browser and is completely independent.

These errors occur because the Socket.IO protocol implements connection retries. This is actually a good thing, not a bad thing. On a production site, when the server goes offline for a moment, maybe as a result of restarting after an upgrade, the retries from the client ensure that the connection is reestablished as soon as the server is back able to receive traffic.

If you want your client to not attempt to reconnect, you can configure it as follows:

var socket = io.connect('http://server.com', {
    reconnection: false
});
  • Related