Rechercher dans la communauté
Affichage des résultats pour les étiquettes 'asynchrone'.
2 résultats trouvés
-
Utilisation de net.HTTPClient() asynchrone - dans une scène en LUA sur HC2/HC3 - - dans un QuickApp sur HC3 - Dans les scènes, Fibaro ne nous laisse pas le choix, dès que l'on veut faire des appels HTTP, on est obligé d'utiliser la fonction asynchronse net.HTTPClient(). La fonction Net.FHTTP() synchrone utilisée dans les VD n'est pas disponible dans les scènes. Toutefois, l'avantage de net.HTTPClient() est d'accepter les connexions sécurisées HTTPS devenues majoritaires sur Internet. Exemple de code simple pour une requête de type GET local http = net.HTTPClient() http:request("http://1.2.3.4/url", { success = function(response) if response.status == 200 then print('OK, réponse : '.. response.data) else print("Erreur : status=" .. tostring(response.status)) end end, error = function(err) print("Erreur : " .. err) end, options = { method = 'GET' } }) L'exemple suivant effectue une requête de type POST permettant d'envoyer des données vers le site distant. De plus, la fonction success() récupère les données de type JSON en vue d'un traitement ultérieur (notez que les données envoyées vers le site Web et les données reçues depuis le site Web sont différentes, cela dépend de l'application qui tourne sur le site) : -- Les données à envoyer au formulaire local myJson = { "couleurs": { [1] = "bleu", [2] = "blanc", [3] = "rouge" }, "fruits": { [1] = "pomme", [2] = "banane" }, } -- Appel HTTPS local http = net.HTTPClient() http:request("https://www.domaine.com/url", { success = function(response) if response.status == 200 then if response.data and response.data ~= "" then print('Retour : '.. response.data) local jsonTable = json.decode(response.data) -- Parcours de la table JSON local k, v for k, v in pairs(jsonTable) do print("key = " .. k .. " - type(v) = " .. type(v)) end -- Ici la suite du code, exécuté en asynchrone, donc après la fin de l'exécution du code appelant http:request() -- ... else print("Error : empty response data") end else print("Erreur : status=" .. tostring(response.status)) end end, error = function(err) print("Erreur : " .. err) end, options = { method = 'POST', timeout = 5000, checkCertificate = false, headers = { ["content-type"] = 'application/x-www-form-urlencoded;', ["Authorization"] = "Basic YWRtaW46cGFzc3dvcmQ=" -- username:password encodé en Base64 (admin:password) }, data = json.encode(myJson) } }) -- Ici la suite du code, exécuté en synchrone, donc avant l'exécution du contenu de la fonction success() -- ... On remarque dans les options que l'on peut choisir les paramètres suivants : method : obligatoire : GET ou PUT ou POST ou DELETE timeout : facultatif : délai d'attente en millisecondes avant échec de la requête. Peut être utile avec certains serveurs un peu trop lents à répondre. Dans le doute, inutile d'utiliser ce paramètre. checkCertificate : facultatif : true ou false, permet d'ignorer les alertes de sécurité sur les certificats auto-signés (non reconnus pas une autorité de certification approuvée) headers : facultatif : permet de passer le(s) en-tête(s) HTTP de son choix vers le site Web distant. Si vous ne savez pas ce qu'est un Header, c'est que vous n'avez probablement pas besoin d'envoyer de header, donc ignorez ce paramètre. data : facultatif : ce sont les données à envoyer dans les formulaires POST et PUT sous forme de chaine de caractères. Donc si les données sont de type tableau JSON, il faut les encoder avec json.encode(). Asynchronisme net.HTTPClient() est asynchrone, le code dans les fonctions success() et error() appelées en callback s'exécute toujours après la fin de l'exécution du thread principal. Quand on commence à programmer en asynchrone, il ne faut plus jamais utiliser de fonctions synchrones comme sleep(), sous peine de comportement surprenant. Préférer à la place l'emploi de la fonction settimout() qui est elle-même asynchrone (chercher les exemples sur le forum) La bonne pratique quand on programme en asynchrone est la suivante : Après un appel à net.HTTPClient(), le code devrait se terminer le plus rapidement possible afin de laisser la main à la fonction success() appelée en callback de net.HTTPClient(). La suite du code se déroule donc dans la fonction success(). Celle-ci, à sont tour, peut faire d'autres appels à net.HTTPClient() ou settimeout() pour déclencher de nouveaux appels de fonctions en callback asynchrone. Etc... C'est la technique que j'ai employé dans mes scènes Watchdog et Yamaha MusicCast, partagées sur le forum. C'est une certaine gymnastique qui n'est pas évidente au début, et oblige à revoir toute la structure de son code LUA. En complément je vous invite à lire ce sujet sur la protection des requêtes http avec pcall() :
- 58 réponses
-
- 10
-
bonjour à tous, question de programmation pure et dure Je suis confronté à un problème plutôt bloquant me concernant. Dans une scène (gestion de 12 mi-flora avec VD, consignes d'humidité, alertes mail, ... bref), je souhaite créer des variables globales dynamiquement. j'utilise pour cela ce bout de code (simplifié), qui marche très bien, placé dans une fonction : function TestGlobal(id) local http = net.HTTPClient() if fibaro:getGlobal(id) == nil then --si pas de VG --nouvelle variable newVar = {} newVar.name = id newVar.value = "0" http:request("http://127.0.0.1:11111/api/globalVariables", { options = {method = 'POST', data = json.encode(newVar)}, success = function(response) print("Création de la variable "..id) end, error = function(response) print("Error: " ..response) end, }) end end MAIS cette fonction est appelée en premier, pour ensuite exécuter d'autres fonctions utilisant justement les VG créées. Et bien ça marche pô ! Si j'analyse bien mon script complet, les VG ne sont même pas créées !!!! J'ai pas le print du success !!!! ni celui du error... pourquoi ???? Et le plus dingue, c'est que si je n'exécute pas les fonctions qui suivent, celle de la création de VG fonctionne très bien, les VG sont alors crées !!! d'après mes recherches et essais cela viendrait du mode asynchrone de l'execution du net.HTTPClient. Mais alors comment le contourner ??? J'ai déjà été confronté à ce genre de soucis, que j'ai pu contourner en imbriquant les net.HTTPClient , mais le code devient très illisible et compliqué. (exemple pour des scènes qui gère la patrouille de caméras, 7 positions PTZ déterminées = 7 net.HTTPClient qui s'imbriquent ) Mais la clairement dans ma scène actuelle, je ne peux pas faire ce genre d'emboitement. Merci pour votre aide !!