Codifica della febbre da cabina: un tutorial sul back-end di Node.js
Pubblicato: 2022-03-11Il blocco del COVID-19 ha molti di noi bloccati a casa, forse sperando che la semplice febbre da cabina sia il peggior tipo di febbre che sperimenteremo. Molti di noi stanno consumando più contenuti video che mai. Sebbene l'esercizio sia particolarmente importante in questo momento, a volte c'è nostalgia per il lusso di un buon telecomando vecchio stile quando il laptop è fuori portata.
È qui che entra in gioco questo progetto: l'opportunità di trasformare qualsiasi smartphone, anche uno vecchio che altrimenti sarebbe inutile per mancanza di aggiornamenti, in un comodo telecomando per il prossimo Netflix/YouTube/Amazon Prime Video/ecc. binge-watch. È anche un tutorial per il back-end di Node.js: un'opportunità per apprendere le basi del JavaScript di back-end utilizzando il framework Express e il motore di modelli Pug (ex Jade).
Se sembra scoraggiante, alla fine verrà presentato il progetto Node.js completo; i lettori devono solo imparare tanto quanto sono interessati ad apprendere, e ci sarà un discreto numero di spiegazioni più delicate di alcune nozioni di base lungo il percorso che i lettori più esperti possono saltare.
Perché non solo...?
I lettori potrebbero chiedersi: "Perché iniziare a codificare un back-end Node.js?" (A parte l'opportunità di apprendimento, ovviamente.) "Non c'è già un'app per questo?"
Certo, molti di loro. Ma ci sono due ragioni principali per cui questo potrebbe non essere desiderabile:
- Per coloro che cercano di riutilizzare un telefono più vecchio, questa potrebbe semplicemente non essere più un'opzione , come nel caso del dispositivo Windows Phone 8.1 che volevo utilizzare. (L'app store è stato ufficialmente chiuso alla fine del 2019.)
- Fiducia (o mancanza di essa). Come tante app che si trovano su qualsiasi piattaforma mobile, spesso richiedono agli utenti di concedere molte più autorizzazioni di quelle necessarie all'app per ciò che pretende di fare. Ma anche se questo aspetto è adeguatamente limitato, la natura di un'app di controllo remoto significa che gli utenti devono ancora fidarsi del fatto che gli sviluppatori di app non stiano abusando dei loro privilegi sul lato desktop della soluzione includendo spyware o altro malware.
Questi problemi esistono da molto tempo e sono stati anche la motivazione per un progetto simile del 2014 trovato su GitHub. nvm
semplifica l'installazione di versioni precedenti di Node.js e, anche se alcune dipendenze richiedevano l'aggiornamento, Node.js aveva un'ottima reputazione per essere compatibile con le versioni precedenti.
Sfortunatamente, Bitrot ha vinto. Un approccio ostinato e la compatibilità del back-end di Node.js non potevano competere con le infinite deprecazioni e gli impossibili loop di dipendenza tra le vecchie versioni di Grunt, Bower e dozzine di altri componenti. Ore dopo, era più che chiaro che sarebbe stato molto più facile ricominciare da zero, nonostante il consiglio di questo autore di non reinventare la ruota.
Nuovi aggeggi dal vecchio: riutilizzare i telefoni come telecomandi utilizzando un back-end Node.js
Prima di tutto, nota che questo progetto Node.js è attualmente specifico per Linux, sviluppato e testato su Linux Mint 19 e Linux Mint 19.3, in particolare, ma potrebbe sicuramente essere aggiunto il supporto per altre piattaforme. Potrebbe già funzionare su un Mac.
Supponendo che sia installata una versione moderna di Node.js e che un prompt dei comandi sia aperto in una nuova directory che fungerà da root del progetto, siamo pronti per iniziare con Express:
npx express-generator --view=pug
Nota: qui, npx
è uno strumento utile fornito con npm
, il gestore di pacchetti Node.js fornito con Node.js. Lo stiamo usando per eseguire il generatore di scheletri dell'applicazione Express. Nel momento in cui scrivo, il generatore crea un progetto Express/Node.js che, per impostazione predefinita, utilizza ancora un motore di modelli chiamato Jade, anche se il progetto Jade si è rinominato "Pug" dalla versione 2.0 in poi. Quindi, per essere aggiornati e utilizzare Pug immediatamente, inoltre, evitare avvisi di deprecazione, attacchiamo --view=pug
, un'opzione della riga di comando per lo script express-generator
eseguito da npx
.
Una volta fatto, dobbiamo installare alcuni pacchetti dall'elenco delle dipendenze appena popolato del nostro progetto Node.js in package.json
. Il modo tradizionale per farlo è eseguire npm i
( i
per "installa"). Ma alcuni preferiscono ancora la velocità di Yarn, quindi se l'hai installata, esegui semplicemente il yarn
senza parametri.
In questo caso, dovrebbe essere sicuro ignorare l'avviso di deprecazione (si spera che venga presto risolto) da una delle dipendenze secondarie di Pug, a condizione che l'accesso sia mantenuto in base alle necessità sulla rete locale.
Un rapido yarn start
o npm start
, seguito dalla navigazione in localhost:3000
in un browser, mostra che il nostro back-end Node.js di base basato su Express funziona. Possiamo ucciderlo con Ctrl+C
.
Esercitazione sul back-end di Node.js, Passaggio 2: come inviare sequenze di tasti sul computer host
Con la parte remota già a metà, rivolgiamo la nostra attenzione alla parte di controllo . Abbiamo bisogno di qualcosa che possa controllare a livello di codice la macchina su cui eseguiremo il nostro back-end Node.js, fingendo che stia premendo i tasti sulla tastiera.
Per questo, installeremo xdotool
usando le sue istruzioni ufficiali. Un rapido test del loro comando di esempio in un terminale:
xdotool search "Mozilla Firefox" windowactivate --sync key --clearmodifiers ctrl+l
...dovrebbe fare esattamente quello che dice, supponendo che Mozilla Firefox sia aperto in quel momento. Va bene! È facile fare in modo che il nostro progetto Node.js chiami strumenti da riga di comando come xdotool
, come vedremo presto.
Esercitazione sul back-end di Node.js, Passaggio 3: Progettazione delle funzionalità
Questo potrebbe non essere vero per tutti, ma personalmente trovo che molti moderni telecomandi fisici abbiano circa cinque volte più pulsanti che userò mai. Quindi, per questo progetto, stiamo esaminando un layout a schermo intero con una griglia tre per tre di pulsanti belli, grandi e facili da individuare. Dipende dalle preferenze personali quali potrebbero essere quei nove pulsanti.
Si scopre che le scorciatoie da tastiera anche per le funzioni più semplici non sono identiche su Netflix, YouTube e Amazon Prime Video. Né questi servizi funzionano con chiavi multimediali generiche come è probabile che faccia un'app di lettore musicale nativa. Inoltre, alcune funzioni potrebbero non essere disponibili con tutti i servizi.
Quindi quello che dovremo fare è definire un layout di controllo remoto diverso per ciascun servizio e fornire un modo per passare da uno all'altro.
Definire i layout del telecomando e mapparli sulle scorciatoie da tastiera
Facciamo un rapido prototipo funzionante con una manciata di preset. Li metteremo in common/preset_commands.js
—“common” perché includeremo questi dati da più di un file:
module.exports = { // We could use ️ but some older phones (eg, Android 5.1.1) won't show it, hence ️ instead 'Netflix': { commands: { '-': 'Escape', '+': 'f', '': 'Up', '⇤': 'XF86Back', '️': 'Return', '': 'Down', '': 'Left', '': 'Right', '': 'm', }, }, 'YouTube': { commands: { '⇤': 'shift+p', '⇥': 'shift+n', '': 'Up', 'CC': 'c', '️': 'k', '': 'Down', '': 'j', '': 'l', '': 'm', }, }, 'Amazon Prime Video': { window_name_override: 'Prime Video', commands: { '⇤': 'Escape', '+': 'f', '': 'Up', 'CC': 'c', '️': 'space', '': 'Down', '': 'Left', '': 'Right', '': 'm', }, }, 'Generic / Music Player': { window_name_override: '', commands: { '⇤': 'XF86AudioPrev', '⇥': 'XF86AudioNext', '': 'XF86AudioRaiseVolume', '': 'r', '️': 'XF86AudioPlay', '': 'XF86AudioLowerVolume', '': 'Left', '': 'Right', '': 'XF86AudioMute', }, }, };
I valori del codice chiave possono essere trovati usando xev
. (Per me, quelli "audio muto" e "riproduzione audio" non erano rilevabili utilizzando questo metodo, quindi ho anche consultato un elenco di chiavi multimediali.)
I lettori potrebbero notare la differenza tra maiuscole e minuscole tra space
e Return
: indipendentemente dal motivo, questo dettaglio deve essere rispettato affinché xdotool
funzioni correttamente. In relazione a questo, abbiamo un paio di definizioni scritte in modo esplicito, ad esempio shift+p
anche se anche P
funzionerebbe, solo per mantenere chiare le nostre intenzioni.
Esercitazione sul back-end di Node.js, Passaggio 4: l'endpoint "chiave" della nostra API (scusate il gioco di parole)
Avremo bisogno di un endpoint su cui eseguire il POST
, che a sua volta simulerà le sequenze di tasti utilizzando xdotool
. Poiché avremo diversi gruppi di chiavi che possiamo inviare (uno per ogni servizio), chiameremo l'endpoint per un particolare group
. Risposteremo l'endpoint degli users
generati rinominando routes/users.js
in routes/group.js
e apportando le modifiche corrispondenti in app.js
:
// ... var indexRouter = require('./routes/index'); var groupRouter = require('./routes/group'); // ... app.use('/', indexRouter); app.use('/group', groupRouter); // ...
La funzionalità chiave è l'utilizzo xdotool
tramite una chiamata alla shell di sistema in routes/group.js
. Codificheremo YouTube
come menu preferito per il momento, solo a scopo di test.
const express = require('express'); const router = express.Router(); const debug = require('debug')('app'); const cp = require('child_process'); const preset_commands = require('../common/preset_commands'); /* POST keystroke to simulate */ router.post('/', function(req, res, next) { const keystroke_name = req.body.keystroke_name; const keystroke_code = preset_commands['YouTube'].commands[keystroke_name]; const final_command = `xdotool \ search "YouTube" \ windowactivate --sync \ key --clearmodifiers ${keystroke_code}`; debug(`Executing ${final_command}`); cp.exec(final_command, (err, stdout, stderr) => { debug(`Executed ${keystroke_name}`); return res.redirect(req.originalUrl); }); }); module.exports = router;
Qui, prendiamo la chiave richiesta "name" dal corpo della richiesta POST
( req.body
) sotto il parametro chiamato keystroke_name
. Sarà qualcosa come ️
. Lo usiamo quindi per cercare il codice corrispondente dall'oggetto commands
di preset_commands['YouTube']
.
Il comando finale è su più di una riga, quindi \
s alla fine di ogni riga unisce tutti i pezzi in un unico comando:
-
search "YouTube"
recupera la prima finestra con "YouTube" nel titolo. -
windowactivate --sync
attiva la finestra recuperata e attende finché non è pronta per ricevere una sequenza di tasti. -
key --clearmodifiers ${keystroke_code}
invia la sequenza di tasti, assicurandosi di cancellare temporaneamente i tasti modificatori come Caps Lock che potrebbero interferire con ciò che stiamo inviando.
A questo punto, il codice presuppone che gli stiamo fornendo un input valido, qualcosa a cui staremo più attenti in seguito.
Per semplicità, il codice presuppone anche che ci sia solo una finestra dell'applicazione aperta con "YouTube" nel titolo: se c'è più di una corrispondenza, non c'è alcuna garanzia che invieremo sequenze di tasti alla finestra prevista. Se questo è un problema, può essere utile modificare i titoli delle finestre semplicemente cambiando le schede del browser su tutte le finestre oltre a quella da controllare a distanza.
Con quello pronto, possiamo riavviare il nostro server, ma questa volta con il debug abilitato in modo da poter vedere l'output delle nostre chiamate di debug
. Per farlo, esegui semplicemente DEBUG=old-fashioned-remote:* yarn start
o DEBUG=old-fashioned-remote:* npm start
. Una volta in esecuzione, riproduci un video su YouTube, apri un'altra finestra del terminale e prova una chiamata cURL:
curl --data "keystroke_name=️" http://localhost:3000/group
Ciò invia una richiesta POST
con il nome della sequenza di tasti richiesto nel suo corpo alla nostra macchina locale sulla porta 3000
, la porta su cui è in ascolto il nostro back-end. L'esecuzione di quel comando dovrebbe generare note npm
Executed
Executing
cosa più importante, aprire il browser e mettere in pausa il suo video. L'esecuzione di quel comando di nuovo dovrebbe dare lo stesso output e riattivarlo.
Esercitazione sul back-end di Node.js, Passaggio 5: layout multipli di controllo remoto
Il nostro back-end non è ancora finito. Ci servirà anche per essere in grado di:
- Produci un elenco di layout di controllo remoto da
preset_commands
. - Produci un elenco di "nomi" di tasti da una volta che abbiamo scelto un particolare layout del telecomando. (Potremmo anche scegliere di usare
common/preset_commands.js
direttamente sul front-end, dato che è già JavaScript, e filtrato lì. Questo è uno dei potenziali vantaggi di un back-end Node.js, semplicemente non lo usiamo qui .)
Entrambe queste funzionalità sono il punto in cui il nostro tutorial sul back-end di Node.js si interseca con il front-end basato su Pug che costruiremo.
Utilizzo del modello Pug per presentare un elenco di telecomandi
La parte back-end dell'equazione significa modificare routes/index.js
in modo che assomigli a questo:
const express = require('express'); const router = express.Router(); const preset_commands = require('../common/preset_commands'); /* GET home page. */ router.get('/', function(req, res, next) { const group_names = Object.keys(preset_commands); res.render('index', { title: 'Which Remote?', group_names, portrait_css: `.group_bar { height: calc(100%/${Math.min(4, group_names.length)}); line-height: calc(100vh/${Math.min(4, group_names.length)}); }`, landscape_css: `.group_bar { height: calc(100%/${Math.min(2, group_names.length)}); line-height: calc(100vh/${Math.min(2, group_names.length)}); }`, }); }); module.exports = router;
Qui, prendiamo i nomi dei nostri layout di controllo remoto ( group_names
) chiamando Object.keys
sul nostro file preset_commands
. Quindi li inviamo e alcuni altri dati di cui avremo bisogno al motore di modelli Pug che viene chiamato automaticamente tramite res.render()
.
Attenzione a non confondere il significato delle keys
qui con le Object.keys
ci fornisce un array (un elenco ordinato) contenente tutte le chiavi delle coppie chiave-valore che compongono un oggetto in JavaScript:

const my_object = { 'a key' : 'its corresponding value' , 'another key' : 'its separate corresponding value' , };
Se osserviamo common/preset_commands.js
, vedremo il modello sopra e le nostre chiavi (nel senso dell'oggetto) sono i nomi dei nostri gruppi: 'Netflix'
, 'YouTube'
, ecc. I loro valori corrispondenti non sono semplici stringhe come my_object
ha sopra: sono oggetti interi stessi, con le loro chiavi, cioè commands
e possibilmente window_name_override
.
Il CSS personalizzato che viene passato qui è, certamente, un po' un trucco. Il motivo per cui ne abbiamo bisogno invece di utilizzare una moderna soluzione basata su flexbox è per una migliore compatibilità con il meraviglioso mondo dei browser mobili nelle loro ancora più meravigliose incarnazioni precedenti. In questo caso, la cosa principale da notare è che in modalità orizzontale, manteniamo i pulsanti grandi mostrando non più di due opzioni per schermata; in modalità ritratto, quattro.
Ma dove viene effettivamente trasformato in HTML da inviare al browser? È qui che entra in views/index.pug
, che vorremmo assomigliare a questo:
extends layout block header_injection style(media='(orientation: portrait)') #{portrait_css} style(media='(orientation: landscape)') #{landscape_css} block content each group_name in group_names span(class="group_bar") a(href='/group/?group_name=' + group_name) #{group_name}
La prima riga è importante: extends layout
significa che Pug prenderà questo file nel contesto di views/layout.pug
, che è una sorta di modello genitore che riutilizzeremo qui e anche in un'altra vista. Dovremo aggiungere un paio di righe dopo la riga di link
in modo che il file finale assomigli a questo:
doctype html html head title= title link(rel='stylesheet', href='/stylesheets/style.css') block header_injection meta(name='viewport', content='user-scalable=no') body block content
Non entreremo nelle basi dell'HTML qui, ma per i lettori che non hanno familiarità con loro, questo codice Pug rispecchia il codice HTML standard che si trova praticamente ovunque. L' aspetto della creazione di modelli inizia con title= title
, che imposta il titolo HTML su qualsiasi valore corrispondente alla chiave del title
dell'oggetto che passiamo Pug tramite res.render
.
Possiamo vedere un aspetto diverso della modellazione di due righe dopo con un block
che header_injection
. I blocchi come questi sono segnaposto che possono essere sostituiti da modelli che estendono quello corrente. (Non correlato, la meta
line è semplicemente una soluzione rapida per i browser mobili, quindi quando gli utenti toccano i controlli del volume un sacco di volte di seguito, il telefono si astiene dallo zoomare avanti o indietro.)
Tornando ai nostri block
: ecco perché views/index.pug
definisce i propri block
con gli stessi nomi che si trovano in views/layout.pug
. In questo caso di header_injection
, questo ci consente di utilizzare CSS specifici per l'orientamento verticale o orizzontale in cui si troverà il telefono.
content
è dove mettiamo la parte principale visibile della pagina web, che in questo caso:
- Passa attraverso l'array
group_names
lo passiamo, - crea un elemento
<span>
per ognuno a cui è applicata la classe CSSgroup_bar
, e - crea un collegamento all'interno di ogni
<span>
basato sugroup_name
.
La classe CSS group_bar
che possiamo definire nel file inserito tramite views/layout.pug
, ovvero public/stylesheets/style.css
:
html, body, form { padding: 0; margin: 0; height: 100%; font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; } .group_bar, .group_bar a, .remote_button { box-sizing: border-box; border: 1px solid white; color: greenyellow; background-color: black; } .group_bar { width: 100%; font-size: 6vh; text-align: center; display: inline-block; } .group_bar a { text-decoration: none; display: block; }
A questo punto, se npm start
è ancora in esecuzione, andando su http://localhost:3000/
in un browser desktop dovrebbero essere visualizzati due pulsanti molto grandi per Netflix e YouTube, con il resto disponibile scorrendo verso il basso.
Ma se li clicchiamo a questo punto, non funzioneranno, perché non abbiamo ancora definito il percorso a cui si collegano (il GET
ting di /group
.)
Mostra il layout del telecomando scelto
Per fare ciò, lo aggiungeremo a routes/group.js
appena prima della riga finale module.exports
:
router.get('/', function(req, res, next) { const group_name = req.query.group_name || ''; const group = preset_commands[group_name]; return res.render('group', { keystroke_names: Object.keys(group.commands), group_name, title: `${group_name.match(/([AZ])/g).join('')}-Remote` }); });
Questo otterrà il nome del gruppo inviato all'endpoint (ad esempio, mettendo ?group_name=Netflix
alla fine di /group/
), e lo userà per ottenere il valore dei commands
dal gruppo corrispondente. Quel valore ( group.commands
) è un oggetto e le chiavi di quell'oggetto sono i nomi ( keystroke_names
) che visualizzeremo sul nostro layout di controllo remoto.
Nota: gli sviluppatori inesperti non avranno bisogno di entrare nei dettagli di come funziona, ma il valore per title
utilizza un po' di espressioni regolari per trasformare i nomi dei nostri gruppi/layout in acronimi, ad esempio, il nostro telecomando YouTube avrà il titolo del browser YT-Remote
. In questo modo, se stiamo eseguendo il debug sulla nostra macchina host prima di provare le cose su un telefono, non avremo xdotool
che afferrerà la finestra del browser del telecomando stesso, invece di quella che stiamo cercando di controllare. Nel frattempo, sui nostri telefoni, il titolo sarà carino e breve, se vogliamo aggiungere il telecomando ai segnalibri.
Come con il nostro precedente incontro con res.render
, questo sta inviando i suoi dati per mescolarsi con il modello views/group.pug
. Creeremo quel file e lo riempiremo con questo:
extends layout block header_injection script(type='text/javascript', src='/javascript/group-client.js') block content form(action="/group?group_name=" + group_name, method="post") each keystroke_name in keystroke_names input(type="submit", name="keystroke_name", value=keystroke_name, class="remote_button")
Come con views/index.pug
, stiamo sovrascrivendo i due blog da views/layout.pug
. Questa volta, non stiamo inserendo CSS nell'intestazione, ma alcuni JavaScript lato client, di cui parleremo a breve. (E sì, in un momento di perspicacia, ho rinominato i javascripts
pluralizzati in modo errato…)
Il content
principale qui è un modulo HTML composto da un gruppo di diversi pulsanti di invio, uno per ogni keystroke_name
. Ogni pulsante invia il modulo (effettuando una richiesta POST
) utilizzando il nome della sequenza di tasti che sta visualizzando come valore che sta inviando con il modulo.
Avremo anche bisogno di un po' più di CSS nel nostro foglio di stile principale:
.remote_button { float: left; width: calc(100%/3); height: calc(100%/3); font-size: 12vh; }
In precedenza, quando abbiamo impostato l'endpoint, abbiamo finito di gestire la richiesta con:
return res.redirect(req.originalUrl);
Ciò significa in effetti che quando il browser invia il modulo, il back-end di Node.js risponde dicendo al browser di tornare alla pagina da cui è stato inviato il modulo, ovvero il layout principale del telecomando. Sarebbe più elegante senza cambiare pagina; tuttavia, vogliamo la massima compatibilità con lo strano e meraviglioso mondo dei browser mobili decrepiti. In questo modo, anche senza alcun JavaScript front-end funzionante, il nostro progetto back-end Node.js dovrebbe comunque funzionare.
Un pizzico di JavaScript front-end
Lo svantaggio dell'utilizzo di un modulo per inviare le sequenze di tasti è che il browser deve attendere e quindi eseguire un viaggio di andata e ritorno aggiuntivo: la pagina e le sue dipendenze devono quindi essere richieste dal nostro back-end Node.js e consegnate. Quindi, devono essere renderizzati di nuovo dal browser.
I lettori potrebbero chiedersi quanto possa avere questo effetto. Dopotutto, la pagina è minuscola, le sue dipendenze sono estremamente minime e il nostro progetto Node.js finale verrà eseguito su una connessione wifi locale. Dovrebbe essere una configurazione a bassa latenza, giusto?
A quanto pare, almeno durante i test su smartphone più vecchi con Windows Phone 8.1 e Android 4.4.2, l'effetto è purtroppo abbastanza evidente nel caso comune di toccare rapidamente per aumentare o ridurre il volume di riproduzione di qualche tacca. Ecco dove JavaScript può aiutare, senza togliere il nostro grazioso fallback di POST
manuali tramite moduli HTML.
A questo punto, il JavaScript del nostro client finale (da inserire in public/javascript/group-client.js
) deve essere compatibile con i vecchi browser mobili non più supportati. Ma non ci serve molto:
(function () { function form_submit(event) { var request = new XMLHttpRequest(); request.open('POST', window.location.pathname + window.location.search, true); request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.send('keystroke_name=' + encodeURIComponent(event.target.value)); event.preventDefault(); } window.addEventListener("DOMContentLoaded", function() { var inputs = document.querySelectorAll("input"); for (var i = 0; i < inputs.length; i++) { inputs[i].addEventListener("click", form_submit); } }); })();
Qui, la funzione form_submit
invia semplicemente i dati tramite una chiamata asincrona e l'ultima riga impedisce il normale comportamento di invio dei browser, per cui una nuova pagina viene caricata in base alla risposta del server. L'ultima metà di questo frammento di codice attende semplicemente che la pagina venga caricata e quindi collega tutti i pulsanti di invio per utilizzare form_submit
. Il tutto è avvolto in un IIFE.
Tocchi finali
Ci sono una serie di modifiche ai frammenti di cui sopra nella versione finale del nostro codice tutorial back-end Node.js, principalmente allo scopo di una migliore gestione degli errori:
- Il back-end di Node.js ora controlla i nomi dei gruppi e le sequenze di tasti inviate per assicurarsi che esistano. Questo codice si trova in una funzione che viene riutilizzata per entrambe le funzioni
GET
ePOST
diroutes/group.js
. - In caso contrario, utilizziamo il modello di
error
Pug. - JavaScript e CSS front-end ora fanno apparire temporaneamente i pulsanti in grigio in attesa di una risposta dal server, verde non appena il segnale è passato attraverso
xdotool
e ritorno senza problemi e rosso se qualcosa non ha funzionato come previsto . - Il back-end di Node.js stamperà una traccia dello stack se muore, il che sarà meno probabile dato quanto sopra.
I lettori sono invitati a esaminare (e/o clonare) il progetto Node.js completo su GitHub.
Esercitazione sul back-end di Node.js, Passaggio 5: un test nel mondo reale
È ora di provarlo su un telefono reale collegato alla stessa rete wifi dell'host che esegue npm start
e un lettore di film o musica. È solo questione di puntare il browser web di uno smartphone all'indirizzo IP locale dell'host (con suffisso :3000
), che è probabilmente più facile da trovare eseguendo hostname -I | awk '{print $1}'
hostname -I | awk '{print $1}'
in un terminale sull'host.
Un problema che gli utenti di Windows Phone 8.1 potrebbero notare è che il tentativo di accedere a qualcosa come 192.168.2.5:3000
visualizzerà un messaggio di errore:
Per fortuna, non c'è bisogno di scoraggiarsi: semplicemente anteponendo http://
o aggiungendo un finale /
lo fa recuperare l'indirizzo senza ulteriori reclami.
Scegliere un'opzione lì dovrebbe portarci a un telecomando funzionante.
Per maggiore comodità, gli utenti potrebbero voler regolare le impostazioni DHCP del proprio router per assegnare sempre lo stesso indirizzo IP all'host e aggiungere ai preferiti la schermata di selezione del layout e/o qualsiasi layout preferito.
Richieste di pull Benvenuti
È probabile che non tutti apprezzeranno questo progetto esattamente com'è. Ecco alcune idee per miglioramenti, per chi volesse approfondire il codice:
- Dovrebbe essere semplice modificare i layout o aggiungerne di nuovi per altri servizi, come Disney Plus.
- Forse alcuni preferirebbero un layout "modalità luce" e l'opzione per passare da una all'altra.
- Ritirarsi da Netflix, dal momento che non è reversibile, potrebbe davvero usare un "sei sicuro?" una sorta di conferma.
- Il progetto trarrebbe sicuramente vantaggio dal supporto di Windows.
- La documentazione di
xdotool
menziona OSX: questo progetto (o potrebbe funzionare su un Mac moderno? - Per il relax avanzato, un modo per cercare e sfogliare i film, invece di dover scegliere un singolo film Netflix/Amazon Prime Video o creare una playlist di YouTube sul computer.
- Una suite di test automatizzata, nel caso in cui una qualsiasi delle modifiche suggerite interrompa la funzionalità originale.
Spero che questo tutorial sul back-end di Node.js ti sia piaciuto e di conseguenza un'esperienza multimediale migliorata. Buon streaming e codifica!