Flask-SocketIO确保套接字与客户端正确断开连接

时间:2020-05-20 18:55:44

标签: python flask flask-socketio

我在我的Flask应用程序中添加了Flask-SocketIO库,以处理实时连接,并在用户完成特定操作后使用发送到后端的cookie对其进行测试。这是为了防止用户在向URL发出另一个HTTP请求之前关闭其浏览器或网页。我发现浏览器将不会保存在JavaScript中使用document.cookie设置的cookie,直到它从服务器收到响应返回的cookie。由于添加了WebSocket并在开发环境中对其进行了测试,因此套接字确实可以正确发出cookie。但是,当我尝试在终端中使用ctrl-C时,它不会触发信号,即使关闭终端和浏览器/网页后,localhost仍在侦听端口。我知道如何使用taskkill手动终止该进程,但是我担心的是,与客户端的套接字连接在他们关闭了网页/浏览器后仍然保持打开状态。我假设这可能对后端的性能不利,并且可能引起一些安全风险,尽管我不确定。这可能是因为我没有正确处理套接字连接和后端发出的消息,但这是因为文档中的示例代码难以理解。这里是文档:https://flask-socketio.readthedocs.io/en/latest/

有人可以回答这个问题吗?

__ init __。py:

from flask import Flask, url_for, current_app
from flask_socketio import SocketIO

csp = {
    "default-src": [
        "'self'",
        'https://www.youtube.com'
    ],
    'script-src': [ "'self'",
                    'https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js',
                    'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js',
                    'https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js'],
    'style-src': ["'self'",
                  'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css'],
    'img-src': ["'self'",
                'data:',
                'https://i.ytimg.com' ],
    'font-src': ['data:']
}

config = {
    "CACHE_TYPE": "simple",
    "DEBUG": True,
    "SQLALCHEMY_DATABASE_URI": "sqlite:///site.db",
    "SQLALCHEMY_TRACK_MODIFICATIONS": False,
    "SQLALCHEMY_ECHO": False
}
socketio = SocketIO()
def create_app():
    app = Flask(__name__)
    app.config.from_mapping(config)
    socketio.init_app(app)

    from flask_app.main.routes import main
    app.register_blueprint(main)
    with app.app_context():
        db.create_all()
        socketio.run(current_app)

    return app

main / routes.py:

from flask import render_template, session, request, current_app, Blueprint, redirect, url_for, json, make_response
from flask_app import cache
import os

main = Blueprint("main", __name__)

@main.route("/")
def index():
    return render_template("index.html", title="Home")

@main.context_processor
def inject_template_scope():
    injections = dict()

    # Use this method to check if the client has consented to the use of cookies.
    def cookies_check():
        value = request.cookies.get('consent')
        return value != None
    injections.update(cookies_check=cookies_check)
    return injections

run.py:

from flask_app import create_app

base.html:

<html>
 <body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"
    integrity="sha256-yr4fRk/GU1ehYJPAs8P4JlTgu0Hdsp4ZKrx8bDEDC3I="
    crossorigin="anonymous"></script>
 </body>
</html>

base.js:

$(window).on('load', function() {
 function cookieConsent() {
   var socket = io();
   const now = new Date();
   document.cookie = "consent=consented:true,dateTime:" + now + ",lang:" + navigator.language;
   socket.on('connect', function() {
       socket.emit('consent cookie', {consent_cookie: document.cookie});
   });
 }
}

项目层次结构:

project/
|_ flask_app/
   |_ main/
      |_ routes.py
   |_ templates/
      |_ base.html
   |_ static/
      |_ js/
         |_ base.js
   |_ __init__.py
|_ run.py

环境变量:

FLASK_APP : run.py
FLASK_ENV : development

1 个答案:

答案 0 :(得分:0)

socketio.run(app)在端口5000上启动开发服务器。

因此,当您执行flask run时,flask会调用函数create_app()并期望有一个应用程序。但是,由于socketio.run(app)被阻止,您的函数实际上并未返回应用程序。当您按CTRL + C时,它将停止此行。