IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

NodeJS Discussion :

[serialport] Récupérer la réponse après l'envoi d'une trame


Sujet :

NodeJS

  1. #1
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut [serialport] Récupérer la réponse après l'envoi d'une trame
    Bonjour,
    Je débute avec node.js
    Je cherche à communiquer via le port série. J'arrive à envoyer mes trames, j'arrive à afficher la réponse dans la console, mais je n'arrive pas à récupérer la réponse dans une variable pour l'exploiter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const SerialPort = require('serialport');
    const Readline = SerialPort.parsers.Readline;
    const port = new SerialPort('COM5', {autoOpen: true});
    const parser = new Readline();
    port.pipe(parser);
     
    parser.on('data', function (data) { 
    	console.log(data);
    } );
     
    var trame = "toto";
     
    port.write( trame );
    Je pensais déclarer une variable comme var reply ="", avant la ligne parser.on et dans la function faire reply = data;
    Mais ça ne fonctionne pas

    Je pense qu'il me manque quelques bases ...

  2. #2
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    C’est parce que .on() est asynchrone, comme la plupart des fonctions de NodeJS. Tu vois bien data dans ta console ?
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  3. #3
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    oui c'est bien ça !
    En fait je voulais récupérer ma trame pour l'analyser puis la renvoyer vers une page web, mais je crois que le plus simple est de travailler avec les websocket et d’interpréter la trame cote page web et navigateur...

  4. #4
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Comment tu lances ce script ? Tu le fais depuis un terminal, ou bien tu as un serveur qui écoute les requêtes http ?
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  5. #5
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    J'ai créé un script server.js que je lance en local via le terminal sous windows pour le moment : c:\nodejs>node server.js
    Pour l'instant, il écoute le port 1664
    J'arrive à envoyer mes trames et à les recevoir via ma page web quand j'appelle dans le navigateur http://localhost:1664/?a=2&v=3
    La page est dans c:\nodejs

    Je voudrais maintenant faire la même chose en me connectant à distance et en rentrant par le port standard 80.
    Genre appeler l'adresse http://192.168.1.X/?a=2&v=3 et que cela génère et envoie la trame en local avec node.js sur le port série. (exemple typique : allumer une led sur via un Raspberry à distance)

    Dans un premier temps j'essaye donc de passer par un serveur apache local. En parallèle j'ai donc lancé EasyPhp.. et copier ma page dans le dossier www
    J'appelle ma page : http://127.0.0.1:8080/?a=2&v=3 et ça fonctionne mais j’appelle la bibliothèque socket.io.js depuis "l'extérieur"...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.0/socket.io.js"></script>
    Je voudrais l'appeler en local mais ça ne fonctionne pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <script type="text/javascript" src="socket.io.js"></script>
    Edit : ça fonctionne mais j'ai des erreurs dans la console ...

    Erreur dans les liens source : request failed with status 404
    URL de la ressource : http://127.0.0.1:8080/socket/socket.io.js
    URL du lien source : socket.io.js.map[En savoir plus]

  6. #6
    Modérateur
    Avatar de ProgElecT
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2004
    Messages
    6 066
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Décembre 2004
    Messages : 6 066
    Points : 17 098
    Points
    17 098
    Par défaut
    Salut

    Et en mettant le chemin complet src="lectuer/dossier/sousdossier/socket.io.js"
    Soyez sympa, pensez -y
    Balises[CODE]...[/CODE]
    Balises[CODE=NomDuLangage]...[/CODE] quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
    Balises[C]...[/C] code intégré dans une phrase.
    Balises[C=NomDuLangage]...[/C] code intégré dans une phrase quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
    Le bouton en fin de discussion, quand vous avez obtenu l'aide attendue.
    ......... et pourquoi pas, pour remercier, un pour celui/ceux qui vous ont dépannés.
    👉 → → Ma page perso sur DVP ← ← 👈

  7. #7
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Échec du chargement pour l’élément <script> dont la source est « c:/nodejs/node_modules/socket.io/socket.io.js ».
    et la plus rien ne fonctionne

  8. #8
    Modérateur
    Avatar de ProgElecT
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2004
    Messages
    6 066
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Décembre 2004
    Messages : 6 066
    Points : 17 098
    Points
    17 098
    Par défaut
    Tu lances çà avec quel navigateur, FireFox et plus permissif.
    Soyez sympa, pensez -y
    Balises[CODE]...[/CODE]
    Balises[CODE=NomDuLangage]...[/CODE] quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
    Balises[C]...[/C] code intégré dans une phrase.
    Balises[C=NomDuLangage]...[/C] code intégré dans une phrase quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
    Le bouton en fin de discussion, quand vous avez obtenu l'aide attendue.
    ......... et pourquoi pas, pour remercier, un pour celui/ceux qui vous ont dépannés.
    👉 → → Ma page perso sur DVP ← ← 👈

  9. #9
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Je suis avec Firefox

  10. #10
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Salut,

    les solutions que je te propose dans ce post partent du principe que ton script NodeJS sera lui-même le serveur HTTP, ce qui évite de rajouter une couche Apache ou autre.

    Même si tu utilises un serveur Apache pour recevoir les requêtes HTTP, tu devras à un moment ou un autre connecter ton serveur Apache à ton script NodeJS ; ça ne sera pas beaucoup plus facile, tu auras juste rendu l’ensemble plus complexe.

    Pour rendre ton serveur NodeJS accessible depuis une autre machine, tu dois spécifier une adresse IP en plus du port, comme expliqué dans cette réponse sur SuperUser. Je te mets la doc qui va avec.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const Http = require('http');
     
    var server = Http.createServer(function (request, response) { ... });
    server.listen(80, '0.0.0.0');
    L’adresse 0.0.0.0 joue le rôle de joker.
    Dans le contexte d'un serveur, 0.0.0.0 signifie « toutes les adresses IPv4 de la machine locale ».
    https://fr.wikipedia.org/wiki/0.0.0.0
    Grâce à cette adresse joker, tu n’as pas besoin de connaître l’IP de ta machine, ce qui peut t’épargner des efforts si en plus cette IP n’est pas fixe.

    Bien sûr tu devras également configurer routeur, pare-feu, etc. Dans les faits c’est ta machine que tu transformes en serveur HTTP, en la mettant à l’écoute de messages sur le port 80.

    Note : attention à la sécurité quand tu ouvres des ports sur ta machine. vérifie bien au niveau de ton routeur que les paquets entrants sur le port 80 en provenance du réseau extérieur ne peuvent pas passer. On n’est jamais trop prudent…

    La difficulté vient du fait que ton script doit gérer deux flux de données asynchrones : celui qui vient du client (HTTP) et celui qui va vers l’appareil (série). Je me suis creusé la tête mais je n’ai pas trouvé de solution efficace où l’on peut avoir les deux flux initialisés dès le lancement du script. Il faut recréer une connexion série à chaque requête HTTP reçue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    const SerialPort = require('serialport');
    const Http = require('http');
     
    const Readline = SerialPort.parsers.Readline;
     
    var server = http.createServer(function (request, response) {
      console.log(`${new Date().toLocaleString()} ${request.method} ${request.url}`);
      response.writeHead(200, {
        'Content-Type': 'text/plain' // par exemple
      });
     
      var port = new SerialPort('COM5', { autoOpen: true });
      var parser = new Readline();
      port.pipe(parser);
     
      parser.on('error', function (error) {
        console.log(error);
        response.write('Erreur X(');
        response.end();
      });
     
      parser.on('data', function (data) {
        response.write(data);
        response.end();
      });
     
      var trame = 'toto';
      port.write(trame);
    }
     
    server.listen(80, '0.0.0.0');
    console.log('listening on port 80...');
    Je n’ai pas testé mon code alors il y a peut-être (sûrement) des bugs, mais j’espère que tu saisis l’idée

    Edit : Un truc important que j’ai oublié de dire. Note les response.end() dans les écouteurs 'data' et 'error'. Ils sont nécessaires pour fermer le socket HTTP correctement, autrement le navigateur va afficher l’icône de chargement jusqu’à ce que quelqu’un (le client, le serveur ou éventuellement un proxy) décide que c’est un timeout.

    Même quand tout se passe bien, la connexion HTTP reste ouverte le temps que parser se décide à émettre un évènement asynchrone. Pendant ce délai, le navigateur continue d’afficher l’icône de chargement. Si la communication sur le port série prend un certain temps, ça peut être humainement perceptible. C’est un comportement normal, mais ça peut être désagréable. Pour contourner ça, on peut par exemple utiliser WebSocket.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  11. #11
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    oui j'ai bien fais un truc dans ce genre là j'ai utilisé socket.io aussi, mais je crois que j'aurais pu m'en passer...

    je n'arrive pas en local avec le port 80, mais ça doit être normal... j'ai node.js sur mon pc et sur le même PC je lance ma page via un navigateur.. donc le port 80 n'est pas le bon puisque que je suis sur la même "machine" ?
    en tout cas avec un port et le php qui tourne en // ça fonctionne.

    reste à mettre tout ça sur un Raspberry pour tester avec le port 80 (sans apache qui n'apporte rien dans mon cas) .. et avec un navigateur d'un autre ordinateur sur le réseaux.

  12. #12
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Essaye avec un autre port pour voir ? Chez moi quand WAMPServer tourne, je ne peux pas utiliser le port 80. J’imagine qu’avec EasyPHP c’est la même chose.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  13. #13
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Non mais j'ai fermé EasyPhp
    Je vais pas me prendre la tête, j'attends mon Raspberry pour poursuivre mes tests.

    En attendant, je vais réfléchir pour réécrire mon serveur pour me passer de socket.io.

    Est-ce qu'on peut forcer un timeout sur le serveur pour renvoyer une erreur si la com n'est pas opérationnelle ?

  14. #14
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    En fait y’a tout un tas de candidats à l’obstruction du port 80 sous Windows. J’ai trouvé cette page (en anglais) qui explique vite fait comment utiliser netstat pour trouver le coupable.

    Est-ce qu'on peut forcer un timeout sur le serveur pour renvoyer une erreur si la com n'est pas opérationnelle ?
    Bien sûr. Tu peux le faire suivant l’API : https://nodejs.org/api/http.html#htt...msecs_callback
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ...
     
    var server = http.createServer(function (request, response) {
      ...
    });
     
    server.timeout = 5000; // 5 s
    server.listen(80, '0.0.0.0');
    console.log('listening on port 80...');
    Mais ça ne te permettra pas d’envoyer un message au client (même avec la version callback — le socket est déjà détruit quand la callback est appelée).

    Sinon tu peux le faire à la main avec un bon vieux setTimeout :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var server = http.createServer(function (request, response) {
      setTimeout(function () {
        response.write('timeout!');
        response.end();
      }, 5000);
      ...
    });
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  15. #15
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Bonjour,
    J'ai donc repris mon script en virant la partie socket.io
    J'ai presque quelque chose de bien... sauf que quand je lance ma page une deuxième fois j'ai une erreur

    Error: write after end
    Voici à quoi ressemble mon script :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    var http = require('http');
    var url = require('url');
    var fs = require('fs');
    var serialport = require('serialport');
    var Readline = serialport.parsers.Readline;
     
    var port = new serialport('COM5', {autoOpen: true});
    var parser = new Readline();
    port.pipe(parser);
     
    var server = http.createServer(function(request, response) {
        fs.readFile('index.html', 'utf-8', function(err, content) {
    		if (err) {
    		  response.writeHead(404, {'Content-Type': 'text/html'}); //display 404
    		  return response.end("404 Not Found");
    		}
     
    		response.writeHead(200, {"Content-Type": "text/html"});
    		response.write(content);
     
    		var param = url.parse(request.url, true).query;
     
    		var adr_SL = parseInt(param.sl, 10);
    		var val_SL = parseInt(param.v, 10);
     
    		if( !isNaN(adr_SL) && !isNaN(val_SL) )
    		{
    			var trame = ...;
    			port.write(trame);
    		}
    		else
    		{
    			port.write(trame_status);
    		}
     
    		port.on('error', function(err) {
    			response.write('Erreur' + err);
    			response.end('</body></html>');
    		});
     
    		parser.on('data', function (data) { 
    			if( data.length > 18 )
    			{
    				//reply status
    				response.write(data);
    				response.end('</body></html>');
    			}
    			else
    			{
    				response.write(data+'</br>');
    				port.write(trame_status);
    			}
    		});
    	});
    });
     
    server.listen(1664);
    PrintLog('WebServer is running at http://localhost:1664/');
    Un autre truc: je ne vois pas comment intégrer le timeout la dedans ?

  16. #16
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Tu peux mettre Le timeout, au choix, au début de la callback de .createServer(), ou bien au début de celle de .readFile(). Comme a priori tu auras toujours besoin de lire 'index.html', ça me paraît bien de mettre le timeout dans le readFile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    const TIMEOUT = 15000;
     
    ...
     
    var server = http.createServer(function(request, response) {
      fs.readFile('index.html', 'utf-8', function(err, content) {
        setTimeout(function () {
          response.writeHead(504, {'Content-Type': 'text/html'});
          return response.end('504 Gateway Time-out');
        }, TIMEOUT);
     
        ...
     
      });
    });
    Pour le code HTTP j’ai mis 504 mais c’est un peu au pif. Je l’ai trouvé sur Wikipédia.

    À propos de l’erreur, le message “write after end” ne nous dit pas si le write qui pose problème concerne port ou bien response.

    Pour avoir plus d’informations sur l’erreur, tu peux l’afficher dans la console en plus de l’envoyer au client. Quand elle est envoyée par HTTP, elle est sérialisée en texte et seule sa propriété message est conservée, tu perds les informations de numéro de ligne, pile d’appels, etc.

    Tu peux aussi envoyer explicitement les autres informations d’erreur par HTTP, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        port.on('error', function(err) {
          response.write('Erreur : <pre>' +
            err.message + '\n' + err.stack +
            '</pre>');
          response.end('</body></html>');
        });
    La raison pour laquelle l’erreur n’apparaît qu’à la deuxième requête, c’est que tu ajoutes des écouteurs sur port à chaque requête. La première fois, il n’y a qu’un seul écouteur pour 'error' et un seul pour 'data', tout se passe bien. Mais la fois suivante, il y a un second écouteur 'data', appelé après le premier, qui refait donc un write après que le premier a appelé end.

    C’est pour cette raison que j’avais redéclaré port dans le corps de la fonction du serveur, dans le code que je t’ai donné précédemment. Ainsi, chaque requête gère sa propre « instance » de port.

    Il y a bien une solution à base de removeAllListeners, mais :
    1. elle est considérée comme une mauvaise pratique ;
    2. elle crée un autre problème.


    En effet, si à chaque requête tu effaces les écouteurs précédents de port pour en rattacher des nouveaux, tu ne pourras pas gérer correctement les requêtes concurrentes.

    Ça sera plus clair avec un schéma :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            script Node      port série
                |                |
    requête A   |                |
    ----------->|                |
                | port.write()   |
                |--------------->|
                |                |
    requête B   |                |
    ----------->|           data |
                |<---------------|
                |                |
    La requête B va recevoir les données destinées à la requête A.

    Je sais que je me répète mais c’est compliqué de gérer deux communications asynchrones en même temps. Même dans le cas où chaque requête a sa propre instance de port, je ne suis pas sûr que les données soient routées correctemen au niveau système. Il est possible que .on('data') reçoive indifféremment toutes les données qui arrivent sur le port, et là c’est premier arrivé, premier servi. Je ne sais pas s’il y a une solution parfaite.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  17. #17
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Bonjour,
    Merci pour tous ces détails et ces explications claires.

    J'ai effectivement changé la "localisation" de la déclaration du port et cela fonctionne parfaitement.
    J'ai inclus l'erreur 504, juste que je n'ai pas redéclare le header car je déclare dans mon code le header 200 pour écrire dans la page ... il faudrait que je passe par un "buffer" pour écrire qu'à la fin.. mais je n'en vois pas l'intérêt pour l'instant.

    Je n'ai plus qu'un
    GET /favicon.ico
    qui vient trainer dans la console... surement le navigateur qui envoie cette requête ?

  18. #18
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Citation Envoyé par dark_vidor Voir le message
    J'ai inclus l'erreur 504, juste que je n'ai pas redéclare le header car je déclare dans mon code le header 200 pour écrire dans la page ... il faudrait que je passe par un "buffer" pour écrire qu'à la fin.. mais je n'en vois pas l'intérêt pour l'instant.
    Si tu ne le connais pas déjà, le framework Express gère le buffering, le routage, le templating, et plein d’autres trucs.

    Citation Envoyé par dark_vidor Voir le message
    Je n'ai plus qu'un GET /favicon.ico qui vient trainer dans la console... surement le navigateur qui envoie cette requête ?
    Oui, les navigateurs font automatiquement une requête à cette URL pour obtenir une favicon. Une des nombreuses stupidités que le Web hérite de son passé. Comme indiqué dans How to prevent favicon.ico requests, il n’y a pas vraiment de solution propre, mais tu peux donner un os à ronger au navigateur en ajoutant une balise dans le code HTML.
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />

    Évidemment, cette solution ne s’applique pas si tu sers un autre type de contenu que du HTML…
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  19. #19
    Membre régulier Avatar de dark_vidor
    Homme Profil pro
    Élève
    Inscrit en
    Janvier 2005
    Messages
    321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Élève

    Informations forums :
    Inscription : Janvier 2005
    Messages : 321
    Points : 118
    Points
    118
    Par défaut
    Bonjour,
    J'ai récupéré un raspberry, monté mon serveur nodejs dessus et il se lance parfaitement au démarrage en rajoutant une ligne dans /etc/rc.local

    nodejs /home/pi/server.js "$_IP"
    Mes questions sont maintenant comment vérifier via ssh que le serveur tourne ?
    Comment relancer le script automatiquement s'il y a une erreur js bloquante qui coupe le script ?

  20. #20
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Citation Envoyé par dark_vidor Voir le message
    Mes questions sont maintenant comment vérifier via ssh que le serveur tourne ?
    Je ne sais pas quel système tu utilises sur ton Pi, mais il est assez probable que curl soit disponible. Tu peux vérifier en tapant curl --version. Tu peux t’en servir pour faire des requêtes HTTP en localhost.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    curl http://localhost:1664/
    Si localhost ne marche pas, remplace-le par 127.0.0.1.

    L’option -i (include headers) de curl te permet de voir les en-têtes de la réponse, et l’option -v (verbose) affiche également ceux de la requête. Bien sûr, curl a sa propre page de manuel, n’hésite pas à la consulter.

    Sinon, j’imagine qu’en regardant la liste des processus, par exemple avec ps, tu pourras voir tourner l’interpréteur NodeJS, mais c’est toute la précision que tu auras…

    Citation Envoyé par dark_vidor Voir le message
    Comment relancer le script automatiquement s'il y a une erreur js bloquante qui coupe le script ?
    Là on n’est plus dans le domaine de JavaScript, et je pense que tu auras plus de chances sur un forum consacré au Raspberry Pi, ou à Linux.

    Personnellement je chercherais à mettre en place une tâche périodique, avec un daemon ou cron. Je pense que cron est disponible sur ton Pi. La tâche serait un script shell, qui détecte la présence de NodeJS dans la liste des processus (par exemple pgrep node) et qui relance le serveur s’il ne trouve rien. Mais ça ne marche que s’il n’y a qu’un seul script NodeJS qui tourne sur ton Pi.
    Sinon il faut cibler précisément le processus qui fait tourner ton serveur, et là des outils comme pidof s’avèrent utiles. En fouillant un peu, j’ai trouvé dans cette discussion sur ServerFault la ligne de commande suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sh -c 'echo $$; exec myCommand'
    L’idée ce serait de remplacer la ligne de ton rc.local qui lance directement ton serveur, par un script qui est chargé de

    Pense également à mettre en place un log d’erreurs, pour t’aider à comprendre ce qui se passe quand ton serveur plante. C’est assez simple, il suffit d’utiliser console.error dans ton script, qui envoie des messages vers stderr, et, dans la commande qui lance ton serveur, de rediriger la sortie vers un fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    node server.js 2> error.log
    Sinon je viens de tomber sur foreverjs. Je ne connais pas mais ça a l’air de correspondre assez bien à tes besoins. Jette un œil
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

Discussions similaires

  1. Réponses: 3
    Dernier message: 31/08/2011, 16h20
  2. Réponses: 3
    Dernier message: 06/05/2011, 15h47
  3. Réponses: 8
    Dernier message: 03/05/2010, 12h30
  4. [Réseau] Connexion et envoie d'une trame
    Par ivanoe25 dans le forum Langage
    Réponses: 10
    Dernier message: 29/09/2006, 01h04
  5. Problème avec l'envoi d'une trame TCP
    Par fredoBreton dans le forum API, COM et SDKs
    Réponses: 14
    Dernier message: 17/11/2005, 21h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo