Maison >interface Web >js tutoriel >Comment construire un tableau de bord Wi-Fi à l'aide de Node.js et Racactive.js
<span>function switchConfigForCurrentOS () { </span> <span>switch(process.platform) { </span> <span>case 'linux': </span> <span>return { </span> <span>batteryCommand: 'upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep -E "state|time to empty|to full|percentage"', </span> <span>batteryProcessFunction: processBatteryStdoutForLinux, </span> <span>wifiCommand: 'iwlist wlan0 scanning | egrep "Cell |Address|Channel|Frequency|Encryption|Quality|Signal level|Last beacon|Mode|Group Cipher|Pairwise Ciphers|Authentication Suites|ESSID"', </span> <span>wifiProcessFunction: processWifiStdoutForLinux </span> <span>}; </span> <span>case 'darwin': //MAc OsX </span> <span>... </span> <span>} </span> <span>}</span>
<span>function processWifiStdoutForLinux(stdout) { </span> <span>var networks = {}; </span> <span>var net_cell = ""; </span> <span>var cell = {}; </span> stdout<span>.split('\n').map(trimParam).forEach(function (line) { </span> <span>if (line.length > 0) { </span> <span>//check if the line starts a new cell </span> <span>if (stringStartsWith(line, NET_CELL_PREFIX)) { </span> <span>if (net_cell.length > 0) { </span> networks<span>[net_cell] = mapWifiKeysForLinux(cell); </span> <span>} </span> cell <span>= {}; </span> line <span>= line.split("-"); </span> net_cell <span>= line[0].trim(); </span> line <span>= line[1]; </span> <span>} </span> <span>//Either way, now we are sure we have a non empty line with (at least one) key-value pair </span> <span>// and that cell has been properly initialized </span> <span>processWifiLineForLinux(cell, line); </span> <span>} </span> <span>}); </span> <span>if (net_cell.length > 0) { </span> networks<span>[net_cell] = mapWifiKeysForLinux(cell); </span> <span>} </span> <span>return networks; </span> <span>}</span>Avant de voir dans les détails ce qui se passe à l'intérieur de ProcessWifilineForlinux, permettez-moi de mettre en évidence quelques points:
<span>function switchConfigForCurrentOS () { </span> <span>switch(process.platform) { </span> <span>case 'linux': </span> <span>return { </span> <span>batteryCommand: 'upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep -E "state|time to empty|to full|percentage"', </span> <span>batteryProcessFunction: processBatteryStdoutForLinux, </span> <span>wifiCommand: 'iwlist wlan0 scanning | egrep "Cell |Address|Channel|Frequency|Encryption|Quality|Signal level|Last beacon|Mode|Group Cipher|Pairwise Ciphers|Authentication Suites|ESSID"', </span> <span>wifiProcessFunction: processWifiStdoutForLinux </span> <span>}; </span> <span>case 'darwin': //MAc OsX </span> <span>... </span> <span>} </span> <span>}</span>Cette discussion est la chance idéale de vous montrer une astuce soignée que j'ai récemment "empruntée" à un collègue ingénieur. Il nous permettra d'utiliser une instruction Switch au lieu d'une chaîne d'IP-ELSES.
<span>function processWifiStdoutForLinux(stdout) { </span> <span>var networks = {}; </span> <span>var net_cell = ""; </span> <span>var cell = {}; </span> stdout<span>.split('\n').map(trimParam).forEach(function (line) { </span> <span>if (line.length > 0) { </span> <span>//check if the line starts a new cell </span> <span>if (stringStartsWith(line, NET_CELL_PREFIX)) { </span> <span>if (net_cell.length > 0) { </span> networks<span>[net_cell] = mapWifiKeysForLinux(cell); </span> <span>} </span> cell <span>= {}; </span> line <span>= line.split("-"); </span> net_cell <span>= line[0].trim(); </span> line <span>= line[1]; </span> <span>} </span> <span>//Either way, now we are sure we have a non empty line with (at least one) key-value pair </span> <span>// and that cell has been properly initialized </span> <span>processWifiLineForLinux(cell, line); </span> <span>} </span> <span>}); </span> <span>if (net_cell.length > 0) { </span> networks<span>[net_cell] = mapWifiKeysForLinux(cell); </span> <span>} </span> <span>return networks; </span> <span>}</span>À ce stade, tout ce que nous avons à faire est de créer simplement un rappel qui exécutera la commande, transformera sa sortie et enfin envoie le résultat JSON au client, enveloppé dans la réponse HTTP fournie par HTTP.CreateServer.
<span>function processWifiLineForLinux(cell<span>, line</span>) { </span> <span>var key; </span> <span>var val; </span> line <span>= line.trim(); </span> <span>if (line.length > 0) { </span> <span>switch (true) { </span> <span>case stringStartsWith(line, NET_ADDRESS_PREFIX): </span> line <span>= line.split(':'); </span> line<span>.splice(0, 1); </span> <span>//INVARIANT: Address in the format Address: DC:0B:1A:47:BA:07 </span> <span>if (line.length > 0) { </span> cell<span>[NET_ADDRESS_PREFIX] = line.join(":"); </span> <span>} </span> <span>break; </span> <span>case stringStartsWith(line, NET_QUALITY_PREFIX): </span> <span>//INVARIANT: this line must have a similar format: Quality=41/70 Signal level=-69 dBm </span> line <span>= line.split(NET_SIGNAL_PREFIX); </span> cell<span>[NET_QUALITY_PREFIX] = line[0].split("=")[1].trim(); </span> <span>if (line.length > 1) { </span> cell<span>[NET_SIGNAL_PREFIX] = line[1].split("=")[1].trim(); </span> <span>} </span> <span>break; </span> <span>case stringStartsWith(line, NET_EXTRA_PREFIX): </span> <span>//INVARIANT: this line must have a similar format: Extra: Last beacon: 1020ms ago </span> line <span>= line.split(":"); </span> <span>//we can ignore the prefix of the string </span> <span>if (line.length > 2) { </span> cell<span>[line[1].trim()] = line[2].trim(); </span> <span>} </span> <span>break; </span> <span>default: </span> <span>//INVARIANT: the field must be formatted as "key : value" </span> line <span>= line.split(":"); </span> <span>if (line.length > 1) { </span> <span>//Just stores the key-value association, so that coupling with client is reduced to the min: </span> <span>//values will be examined only on the client side </span> cell<span>[line[0].trim()] = line[1].trim(); </span> <span>} </span> <span>} </span> <span>} </span> <span>return cell; </span> <span>}</span>Pour la dernière étape, notez que nous avons réutilisé la fonction d'onsuccess que nous avions défini facilement pour le point de terminaison de la batterie (même chose pour le gestionnaire onerror).
<span>var server = http.createServer(function (request<span>, response</span>) { </span> <span>var requestUrl = request.url; </span> <span>var filePath = BASE_URL + requestUrl; </span> <span>if (requestUrl === '/' || requestUrl === '') { </span> response<span>.writeHead(301, </span> <span>{ </span> <span>Location: BASE_URL + 'public/demo.html' </span> <span>}); </span> response<span>.end(); </span> <span>} else if (RE_BATTERY.test(requestUrl)) { </span> <span>getBatteryStatus(response, onBatteryInfo, onError); </span> <span>} else if (RE_NETWORKS.test(requestUrl)) { </span> <span>getWifiStatus(response, onWifiInfo, onError); </span> <span>} </span> <span>... </span> <span>}</span>Le double stache {{}}, comme dans la moustache et le guidon, sont des marqueurs de contenu injecté dynamiquement. RACTIVE.js nous permet d'utiliser des expressions et d'exécuter des fonctions à l'intérieur des supports, tant que ces fonctions et les données utilisées sont disponibles à l'échelle mondiale (Math. modèle. Le résultat de l'expression à l'intérieur des supports sera échappé, donc ce sera du texte brut. Mais parfois, vous devrez peut-être ajouter quelques lignes HTML à vos éléments. Il existe une autre façon de le faire, mais si vous pensez vraiment que vous en avez besoin, vous pouvez utiliser Triple-Stache {{{}}}. L'utilisation de triple stache est sûre car les scripts seront échappés et non exécutés, mais il est plus lent que le double stache, vous devriez donc essayer de l'éviter autant que possible.
<span>function switchConfigForCurrentOS () { </span> <span>switch(process.platform) { </span> <span>case 'linux': </span> <span>return { </span> <span>batteryCommand: 'upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep -E "state|time to empty|to full|percentage"', </span> <span>batteryProcessFunction: processBatteryStdoutForLinux, </span> <span>wifiCommand: 'iwlist wlan0 scanning | egrep "Cell |Address|Channel|Frequency|Encryption|Quality|Signal level|Last beacon|Mode|Group Cipher|Pairwise Ciphers|Authentication Suites|ESSID"', </span> <span>wifiProcessFunction: processWifiStdoutForLinux </span> <span>}; </span> <span>case 'darwin': //MAc OsX </span> <span>... </span> <span>} </span> <span>}</span>L'ouverture est une étiquette IF dont la condition est une fonction, ce qui le rendrait bizarre à l'exécution de la fermeture. Nous pouvons donc utiliser un message significatif pour coupler les deux balises, juste pour la maintenance.
<span>function processWifiStdoutForLinux(stdout) { </span> <span>var networks = {}; </span> <span>var net_cell = ""; </span> <span>var cell = {}; </span> stdout<span>.split('\n').map(trimParam).forEach(function (line) { </span> <span>if (line.length > 0) { </span> <span>//check if the line starts a new cell </span> <span>if (stringStartsWith(line, NET_CELL_PREFIX)) { </span> <span>if (net_cell.length > 0) { </span> networks<span>[net_cell] = mapWifiKeysForLinux(cell); </span> <span>} </span> cell <span>= {}; </span> line <span>= line.split("-"); </span> net_cell <span>= line[0].trim(); </span> line <span>= line[1]; </span> <span>} </span> <span>//Either way, now we are sure we have a non empty line with (at least one) key-value pair </span> <span>// and that cell has been properly initialized </span> <span>processWifiLineForLinux(cell, line); </span> <span>} </span> <span>}); </span> <span>if (net_cell.length > 0) { </span> networks<span>[net_cell] = mapWifiKeysForLinux(cell); </span> <span>} </span> <span>return networks; </span> <span>}</span>Le panneau pour les détails du réseau est assez simple: nous ne l'affichons que si nous avons attribué une valeur au champ SelectedNetwork dans notre objet ROCTIVE. Ensuite, nous montrons le nom du réseau (le champ EssID) et affichons toutes les paires de valeurs clés que nous avons reçues du serveur. Ceci vise à obtenir le couplage le plus bas possible, mais bien sûr, vous pouvez les modifier pour mettre en évidence certaines informations ou les afficher de manière plus significative.
<span>function processWifiLineForLinux(cell<span>, line</span>) { </span> <span>var key; </span> <span>var val; </span> line <span>= line.trim(); </span> <span>if (line.length > 0) { </span> <span>switch (true) { </span> <span>case stringStartsWith(line, NET_ADDRESS_PREFIX): </span> line <span>= line.split(':'); </span> line<span>.splice(0, 1); </span> <span>//INVARIANT: Address in the format Address: DC:0B:1A:47:BA:07 </span> <span>if (line.length > 0) { </span> cell<span>[NET_ADDRESS_PREFIX] = line.join(":"); </span> <span>} </span> <span>break; </span> <span>case stringStartsWith(line, NET_QUALITY_PREFIX): </span> <span>//INVARIANT: this line must have a similar format: Quality=41/70 Signal level=-69 dBm </span> line <span>= line.split(NET_SIGNAL_PREFIX); </span> cell<span>[NET_QUALITY_PREFIX] = line[0].split("=")[1].trim(); </span> <span>if (line.length > 1) { </span> cell<span>[NET_SIGNAL_PREFIX] = line[1].split("=")[1].trim(); </span> <span>} </span> <span>break; </span> <span>case stringStartsWith(line, NET_EXTRA_PREFIX): </span> <span>//INVARIANT: this line must have a similar format: Extra: Last beacon: 1020ms ago </span> line <span>= line.split(":"); </span> <span>//we can ignore the prefix of the string </span> <span>if (line.length > 2) { </span> cell<span>[line[1].trim()] = line[2].trim(); </span> <span>} </span> <span>break; </span> <span>default: </span> <span>//INVARIANT: the field must be formatted as "key : value" </span> line <span>= line.split(":"); </span> <span>if (line.length > 1) { </span> <span>//Just stores the key-value association, so that coupling with client is reduced to the min: </span> <span>//values will be examined only on the client side </span> cell<span>[line[0].trim()] = line[1].trim(); </span> <span>} </span> <span>} </span> <span>} </span> <span>return cell; </span> <span>}</span>
<span>var server = http.createServer(function (request<span>, response</span>) { </span> <span>var requestUrl = request.url; </span> <span>var filePath = BASE_URL + requestUrl; </span> <span>if (requestUrl === '/' || requestUrl === '') { </span> response<span>.writeHead(301, </span> <span>{ </span> <span>Location: BASE_URL + 'public/demo.html' </span> <span>}); </span> response<span>.end(); </span> <span>} else if (RE_BATTERY.test(requestUrl)) { </span> <span>getBatteryStatus(response, onBatteryInfo, onError); </span> <span>} else if (RE_NETWORKS.test(requestUrl)) { </span> <span>getWifiStatus(response, onWifiInfo, onError); </span> <span>} </span> <span>... </span> <span>}</span>Nous devons également vérifier que le fichier JSON que nous avons obtenu est bien formaté. Nous n'avons pas à nous soucier de l'injection de script, car Racactive.js échappe déjà aux valeurs du champ avant de les ajouter au DOM. Il convient de noter que la méthode jQuery.getJson (), qui serait un raccourci pour la méthode $ .ajax () utilisée ci-dessus, est sûre tant que: 1. Vous n'incluez pas la chaîne 'callback =' dans votre URL (ce qui permettrait à l'exécution du code JSON).
<span>function switchConfigForCurrentOS () { </span> <span>switch(process.platform) { </span> <span>case 'linux': </span> <span>return { </span> <span>batteryCommand: 'upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep -E "state|time to empty|to full|percentage"', </span> <span>batteryProcessFunction: processBatteryStdoutForLinux, </span> <span>wifiCommand: 'iwlist wlan0 scanning | egrep "Cell |Address|Channel|Frequency|Encryption|Quality|Signal level|Last beacon|Mode|Group Cipher|Pairwise Ciphers|Authentication Suites|ESSID"', </span> <span>wifiProcessFunction: processWifiStdoutForLinux </span> <span>}; </span> <span>case 'darwin': //MAc OsX </span> <span>... </span> <span>} </span> <span>}</span>Pour ce faire, nous définissons un gestionnaire d'événements ad-hoc . Comme mentionné ci-dessus, il sera appelé lorsque nous cliquerons sur n'importe quelle entrée de liste, puis l'événement associé au clic transportera des informations sur le réseau sélectionné lui-même. Maintenant, si nous n'utilisions pas Racactive.js, disons que nous utilisons uniquement jQuery, nous devions:
Pour construire un tableau de bord Wi-Fi, vous devez avoir une compréhension de base de JavaScript et Node.js. Vous devez également que Node.js et NPM (Node Package Manager) soient installés sur votre ordinateur. Si vous ne les avez pas installés, vous pouvez les télécharger sur le site officiel de Node.js. De plus, vous aurez besoin d'un éditeur de texte pour écrire votre code. Vous pouvez utiliser n'importe quel éditeur de texte de votre choix, mais certains populaires incluent le code Visual Studio, l'atome et le texte sublime.
Vous pouvez installer Le module Node-Wifi utilisant NPM, qui est un gestionnaire de packages pour Node.js. Ouvrez votre terminal ou votre invite de commande et accédez au répertoire où vous souhaitez installer le module. Ensuite, exécutez la commande «NPM Install Node-Wifi». Cela téléchargera et installera le module Node-Wifi dans votre répertoire actuel.
Le module Node-WiFi fournit Une fonction «connexion» que vous pouvez utiliser pour vous connecter à un réseau Wi-Fi. Vous devez transmettre un objet à cette fonction qui contient le SSID et le mot de passe du réseau. Voici un exemple:
var wifi = require ('node-wifi');
wifi.connect ({ssid: 'votre nom de réseau', mot de passe: 'votre mot de passe'}, fonction (err) {
if (err) {
console.log (err);
}
console.log ('connecté avec succès au réseau');
});
Le module de nœud-wifi fournit une fonction «scan» que vous pouvez utiliser pour scanner pour les réseaux Wi-Fi disponibles. Cette fonction renvoie un tableau de réseaux. Chaque réseau est un objet qui contient des informations telles que le SSID, la force du signal et le type de sécurité. Voici un exemple:
var wifi = require ('node-wifi');
wifi.scan (fonction (err, réseaux) {
if (err) {
console.log (err);
}
console.log (réseaux);
});
Le nœud- Le module WiFi fournit une fonction «déconnecter» que vous pouvez utiliser pour déconnecter d'un réseau Wi-Fi. Vous n'avez pas besoin de transmettre des arguments à cette fonction. Voici un exemple:
var wifi = require ('node-wifi');
wifi.disconnect (function (err) {
if (err) {
console.log (err. );
}
Console.log («Déconnecté avec succès du réseau»);
});
Le module Node-WiFi fournit une fonction «GetCurrentConnections» que vous pouvez utiliser pour obtenir l'état Wi-Fi actuel. Cette fonction renvoie un tableau de réseaux auxquels l'ordinateur est actuellement connecté. Voici un exemple:
var wifi = require ('node-wifi');
wifi.getCurrentConnections (fonction (err, currentconnections) {
if (err) {
console.log (err);
}
console.log (currentconnections);
});
Le nœud -Le module WIFI suit le modèle standard de gestion des erreurs Node.js. Toutes les fonctions prennent un rappel comme dernier argument. Ce rappel est une fonction qui prend deux arguments: un objet d'erreur et le résultat. Si une erreur se produit, l'objet d'erreur contiendra des informations sur l'erreur. Sinon, l'objet d'erreur sera nul et le résultat contiendra le résultat de l'opération.
Le module Node-WiFi est conçu pour fonctionner sur Windows, MacOS et Linux. Cependant, la fonctionnalité peut varier légèrement entre différents systèmes d'exploitation en raison de différences dans la façon dont ils gèrent les réseaux Wi-Fi.
Oui, vous pouvez utiliser le module Node-Wifi avec d'autres modules Node.js. Par exemple, vous pouvez l'utiliser avec le module Express pour créer un serveur Web qui affiche les réseaux Wi-Fi disponibles.
Le nœud -Le module WIFI est un projet open-source, et les contributions sont les bienvenues. Vous pouvez contribuer en signalant des bogues, en suggérant de nouvelles fonctionnalités, en améliorant la documentation ou en écrivant du code. Pour contribuer, vous pouvez débarquer le projet sur GitHub, apporter vos modifications, puis soumettre une demande de traction.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!