如何使用 Ctrl+C 结束 Flask SocketIO,错误 403(禁止)

Posted

技术标签:

【中文标题】如何使用 Ctrl+C 结束 Flask SocketIO,错误 403(禁止)【英文标题】:How to end Flask SocketIO with Crtl+C, Error 403 (Forbidden) 【发布时间】:2022-01-23 06:53:21 【问题描述】:

如何优雅地结束套接字?我尝试使用signal.SIGINT,但没有成功。

还有其他方法吗?我正在开发中运行,并且在 Crtl+C 之后似乎无法停止套接字。当 app.py 再次启动时,浏览器控制台日志会继续打印并锁定浏览器以防止重新加载页面。

这是我的 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
    )

【问题讨论】:

【参考方案1】:

Ctrl-C 停止服务器。您看到的错误来自客户端,它在浏览器中运行并且完全独立。

出现这些错误是因为 Socket.IO 协议实现了连接重试。这其实是好事,不是坏事。在生产站点上,当服务器暂时离线时,可能是由于升级后重新启动,客户端的重试确保服务器恢复能够接收流量后立即重新建立连接。

如果您希望您的客户端不尝试重新连接,您可以配置如下:

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

【讨论】:

以上是关于如何使用 Ctrl+C 结束 Flask SocketIO,错误 403(禁止)的主要内容,如果未能解决你的问题,请参考以下文章

c 如何结束socket读取

FLASK python web:MySQLdb._exceptions.OperationalError:(2002,“无法通过套接字'/tmp/mysql.sock'连接到本(代码

Ctrl+C 和 Ctrl+[ 有啥区别?

linux系统中挂起操作和强制结束操作(后台运行程序方法)

如何在不使用 ctrl-c 的情况下停止烧瓶应用程序

ctrl+c ctrl+d ctrl+z 的区别和使用场景