Ошибка при использовании Emit from thread с flask socketio python3 - PullRequest
0 голосов
/ 04 февраля 2020

Я пытаюсь создать приложение, которое обслуживает страницу через Интернет с 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 я оставляю это так, я получаю:

('Работа вне контекста запроса. \ n \ n Это обычно означает, что вы пытались использовать функциональность, которая требовалась \ nan активный HTTP-запрос. Обратитесь к документации по тестированию для \ ninformation о том, как избежать этой проблемы. ',)

, если я добавлю сокет. до emit я не получаю ошибку eny, но также я не получаю сообщения

также для меня было бы нормально инициировать событие из потока в основную ветку для отправки сообщений, если статус изменить например, но также я не знаю, как это сделать

пс. я только что добавил ручку getstatus , чтобы выполнить тест для отправки их с кнопки на веб-странице, и она работает, она работает не только в потоке

, возможно, проблема в том, что я ' пытаешься излучать, когда нет связанных сущностей? как это проверить?

1 Ответ

0 голосов
/ 04 февраля 2020

Функция emit() использует некоторые значения по умолчанию, которые исходят из контекста запроса. Если вы хотите использовать эту функцию там, где нет контекста запроса, вам нужно предоставить больше аргументов. В частности, вам нужно добавить room, чтобы указать, кто является получателем сообщения, и namespace.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...