J'essaie de créer une application, qui sert une page via le Web avec un flacon, en attendant, en arrière-plan, démarre un fil qui demande le statut à une autre machine et met à jour une variable. Je voudrais également envoyer ce statut via socketio pour mettre à jour le page Web (si présente, sinon enregistrez simplement les informations)

Malheureusement, je ne suis pas en mesure de le faire, je rencontre un problème lors de l'envoi ou de la réception des messages

ici le code 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)

Voici le code js pour obtenir le message socket :

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

Le problème que j'obtiens est que si dans la fonction getStatus je le laisse comme ceci, j'obtiens :

("Travail en dehors du contexte de la demande.\n\nCela signifie généralement que vous avez essayé d'utiliser une fonctionnalité qui nécessitait\nune requête HTTP active. Consultez la documentation sur les tests pour\ndes informations sur la façon d'éviter ce problème.',)

Si j'ajoute socket. avant l'émission, je ne reçois aucune erreur, mais je ne reçois pas non plus les messages

Aussi pour moi ce serait ok de déclencher un événement du thread au mainthread pour envoyer les messages si le statut change par exemple, mais aussi je ne sais pas comment le faire

Ps. je viens d'ajouter un gestionnaire getstatus pour faire des tests en les envoyant à partir d'un bouton sur la page Web et cela fonctionne, cela ne fonctionne pas uniquement dans le fil

Peut-être que le problème est que j'essaie d'émettre alors qu'il n'y a pas d'entités connectées ? comment vérifier ça ?

1
Darkmagister 4 févr. 2020 à 01:26

1 réponse

Meilleure réponse

La fonction emit() utilise certaines valeurs par défaut qui proviennent du contexte de la requête. Si vous souhaitez utiliser cette fonction dans un endroit où il n'y a pas de contexte de requête, vous devez fournir plus d'arguments. En particulier, vous devez ajouter room pour indiquer qui est le destinataire du message, et namespace.

0
Miguel 4 févr. 2020 à 12:26