使用 Flask socketio 从线程发出错误 python3

Error Using Emit from thread with flask socketio python3

我正在尝试构建一个应用程序,它通过带有 flask 的网络提供页面,同时在后台启动一个线程,它向另一台机器询问状态并更新变量,我也想发送该状态通过 socketio 更新网页(如果存在,否则只保存信息)

不幸的是我无法做到这一点,我在发送或接收消息时遇到了一些问题

这里是python代码:

from time import sleep
from flask import Flask, render_template, request, copy_current_request_context
from flask_sqlalchemy import SQLAlchemy
import sqlalchemy as db
from flask_htpasswd import HtPasswdAuth
from sqlalchemy import desc
from threading import Thread, Event
import datetime
import os
import logging
from flask_socketio import SocketIO, emit
import hashlib

class config():
    hostip = '0.0.0.0'
    portip = 8080

class statoMacchina():
    status = -1
    mode = -1

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socket = SocketIO(app, async_mode='threading')
db = SQLAlchemy(app)

thread = Thread()
thread_stop_event = Event()

class getStatusThread(Thread):
    def __init__(self):
        self.delay = 30
        super(getStatusThread, self).__init__()

    def getStatus(self):
        try:
            print(" try " )
            emit('status', {'mode': statoMacchina.mode, 'status' : statoMacchina.status})
        except Exception as ex:   
            print(ex.args)

            #sleep(self.delay)
    def run(self):
        self.getStatus()

thread = getStatusThread()
thread.start()

@socket.on('getstatus', namespace='/command')
def cmdgetstatus():
    emit('replyesec', {'Esec': "listaaaaaa"})
    #emit('status', {'mode': statoMacchina.mode, 'status' : statoMacchina.status})
    global thread
    if not thread.is_alive():
        print("Starting Thread")
        thread = getStatusThread()
        thread.start()

@app.route("/",methods=['GET'])
def index():
    return render_template(
        'index.html', **locals())

if __name__ == "__main__":
    try:
        tim = datetime.datetime.now()
        print(tim)
        socket.run(app, host=config.hostip, port=config.portip)
    except KeyboardInterrupt:
        print("fine")
    except Exception as ex:
        print(ex.args)

这里是获取套接字消息的js代码:

$(document).ready(function(){
  socket.on('status', function(msg) {
      console.log("status - " + msg);
    $("#statoopc").html(msg.mode + " - " + msg.status);
  });
}

我遇到的问题是,如果在函数 getStatus 中我这样保留它,我会得到:

('Working outside of request context.\n\nThis typically means that you attempted to use functionality that needed\nan active HTTP request. Consult the documentation on testing for\ninformation about how to avoid this problem.',)

如果我添加套接字。在发出之前,我没有收到任何错误,但我也没有收到消息

对我来说,如果状态发生变化,也可以触发从线程到主线程的事件以发送消息,但我也不知道该怎么做

ps。我刚刚添加了一个 getstatus handlear 来做一些测试从网页上的按钮发送那些并且它有效,它不仅在线程中工作

也许问题是我试图在没有连接的实体时发射?如何检查?

emit() 函数使用了一些来自请求上下文的默认值。如果你想在没有请求上下文的地方使用这个函数,那么你必须提供更多的参数。特别是,您需要添加 room 以指示谁是邮件的收件人,以及 namespace.