Node per profani: l’invasione degli ultracorpi fa ancora paura?

All’ indirizzo https://umbriawaycultura.wordpress.com/2020/05/15/node-terrore-dallo-spazio-profondo-prima-puntata/ abbiamo esplorato come node gestisce le transazioni http di richiesta utente per ottenere una risposta, fino ad arrivare a Express. Per chiudere il discorso analizziamo il seguente script base ciaomondo.js e analizziamolo:

const express = require(‘express’);
const app = express();
const port = 3000;
app.get(‘/’, function(request, response) {
response.send(‘Hello, World!’);
});
app.listen(port, function() {
console.log(‘Server listening on http://localhost:’ + port);
});

prima importiamo il modulo (vi siete ricordati di installarlo con npm install express?), poi istanziamo un oggetto express che eredita nella pagina tutta una serie di metodi e di proprietà per gestire le richieste http in modo agevole, con poco codice e la miglior performances. Definisco una porta per visualizzare il mio output. Richiamo una funzione definita di callback, ossia di ritorno dove imposto le transazioni dati su url con il metodo get, dopodiché mi metto in ascolto sulla porta 3000 e assolvo alla mia missione: esaudire la richiesta di scrittura a video ciao mondo! Express è un modulo che si appoggia sulle funzioni middleware, ossia l’oggetto request ha al suo interno una serie di metodi e proprietà che ci consentono di fare innumerevoli cose. Adesso passiamo a parlare di SOCKET, indirizzo https://socket.io/ che nella sua home page si definisce FEATURING THE FASTEST AND MOST RELIABLE REAL-TIME ENGINE, che parla di un motore veloce e affidabile. Socket.IO è una libreria javascript per applicazioni web in realtime. Consente la comunicazione in tempo reale e bidirezionale tra client Web e server. Ha due parti: una libreria lato client che viene eseguita nel browser e una libreria lato server per node. In rete sono presenti numerosi tutorial che spiegano bene socket come https://riptutorial.com/it/socket-io per esempio. Immaginiamo dei messaggi tipo twitter che vengono lanciati e visualizzati rapidamente senza pause. Oppure analizziamo il caso reale di una chat dove un utente si registra e invia i suoi messaggi, vediamo il file server.js che cosa fa (diamo per scontato che abbiamo sistemato tutte le inclusioni nella cartella node_modules con i vari comandi di installazione dei pacchetti):

const express = require(‘express’);
const helmet = require(‘helmet’);
const http = require(‘http’);
const socketio = require(‘socket.io’);

var messages = [];

const app = express();
app.use(helmet());

const httpServer = http.Server(app);
const io = socketio(httpServer);

app.get(‘/’, (req, res) => {

res.sendFile(__dirname + ‘/index.html’);

});

app.use(‘/assets’, express.static(‘assets’));

io.on(‘connection’, (socket) => {

messages.forEach((message) => {

socket.emit(‘message’, message.name, message.msg);

});

socket.on(‘message’, (name, msg) => {

messages.push({name: name, msg: msg});
socket.broadcast.emit(‘message’, name, msg);

});

});

httpServer.listen(8080);

L’applicazione richiama una serie di metodi specifici messi a disposizione dal framework coordinati nella cartella script, dove ci saranno tutta una serie di file con estensione js e librerie che serviranno per far funzionarfe il tutto tra cui anche socket.io.js, ovviamente illeggibile se si apre il file compresso tranne la paternità di intestazione:

/*!
* Socket.IO v2.2.0
* (c) 2014-2018 Guillermo Rauch
* Released under the MIT License.
*/

Scrivere un’applicazione di chat con stack di applicazioni Web popolari come LAMP (PHP) è stato normalmente molto difficile. Implica il polling del server per le modifiche, tenere traccia dei timestamp ed è molto più lento di quanto dovrebbe essere. I socket sono stati tradizionalmente la soluzione attorno alla quale sono progettati la maggior parte dei sistemi di chat in tempo reale, fornendo un canale di comunicazione bidirezionale tra un client e un server. Ciò significa che il server può inviare messaggi ai client. Ogni volta che scrivi un messaggio di chat, l’idea è che il server lo riceverà e lo invierà a tutti gli altri client connessi. Si consiglia di consultare la documentazione https://socket.io/get-started/chat/ per approfondimenti e a questo punto non ci resta che passare a Express e alle sessioni. Le sessioni servono in termini di sicurezza per garantire una procedura di login o per salvare dei dati o per garantire il normale funzionamento di un carrello per la spesa. Il materiale in rete non manca come per esempio tutorial https://nodejstutorial.it/expressjs/creare-e-gestire-le-sessioni-in-expressjs. Ma senza un database node sarebbe con una gamba sola, quindi ecco Mongo DB! Si va su https://www.mongodb.com/it e si scarica l’installer che procederà in maniera intuitiva fino a implementare il tutto in locale sulla nostra macchina in C:\Program Files\MongoDB\Server\4.2\bin dove il 4.2 nome della versione può essere variabile a seconda dei casi. Per abilitare le funzionalità del nostro database non andrò come facevo in php myadmin sul gestore database per creare campi e tipo di campi e nome del database prima, qui json mi consente una interazione diretta. L’unico problema è che mi ritrovo a dover ebilitare nella cartella bin un eseguibile di nome mongo.exe come fare? Intanto mi posiziono sulla cartella progetto e quando il cursore punta ai file della mia directory appenderò il percorso completo per azionare l’interruttore con il simbolo” , quindi nel nostro caso dopo il prompt, >”C:\Program Files\MongoDB\Server\4.2\bin\mongo.exe che aprirà il dialogo con il nostro storage in locale. Dopodichè tutte le operazioni di aggiornamento, cancellazione, inserimento vengono gestiti dai metodi proprio di mongodb, vediamo come è composto il nostro server.js che memorizza i dati della nostra chat, in neretto sono evidenziati i punti critici in cui lo script richiama i metodi di mongodb, tutti caratterizzati da db.collection, un oggetto istanziato che ci mette a disposizione varie risorse. Notiamo anche che la riscrittura di messaggi dopo il reload della pagina non viene censurata e anche facendo CTRL + C per interrompere il server e riattivandolo, subito dopo ci ricompare la stessa sequenza precedente senza azzerare nulla:

const express = require(‘express’);
const helmet = require(‘helmet’);
const http = require(‘http’);
const socketio = require(‘socket.io’);
const Session = require(‘express-session’);
const sharedsession = require(“express-socket.io-session”);
const MongoClient = require(‘mongodb’).MongoClient;

var db;

const app = express();
app.use(helmet());

const session = Session({secret: “mySecret”});
app.use(session);

const httpServer = http.Server(app);
const io = socketio(httpServer);

io.use(sharedsession(session, {autoSave:true}));

app.get(‘/’, (req, res) => {

res.sendFile(__dirname + ‘/index.html’);

});

app.use(‘/assets’, express.static(‘assets’));

io.on(‘connection’, (socket) => {

db.collection(‘chatHistory’).find({}).sort({date: 1}).toArray((err, messages) => {

messages.forEach((message) => {

socket.emit(‘message’, message.name, message.msg);

});

});

socket.on(‘name’, (name) => {

socket.handshake.session.name = name;

});

socket.on(‘message’, (msg) => {

db.collection(‘chatHistory’).insertOne({name: socket.handshake.session.name, msg: msg, date: new Date()});
socket.broadcast.emit(‘message’, socket.handshake.session.name, msg);

});

});

const client = new MongoClient(‘mongodb://localhost:27017’);

client.connect((err) => {

if (err) {

return;

}

db = client.db(‘chatHistory’);
httpServer.listen(8080);

});

un modo semplice per collegare mongodb al core node js:

var MongoClient = require(‘mongodb’).MongoClient;//connection with mongoDB
MongoClient.connect(“mongodb://localhost:27017/MyDb”, function (err, db) {
//check the connection
if(err){
console.log(“connection failed.”);
}else{
console.log(“successfully connected to mongoDB.”);
});

per ulteriori approfondimenti cercare in rete argomenti correlati come per esempio: https://riptutorial.com/it/node-js/example/30662/un-modo-semplice-per-collegare-mongodb-con-il-core-node-js . A questo punto c’è un’ altro problema da risolvere, come separare il codice di programmazione javascript dalla pagina HTML. Ad esempio in wordpress c’è un template engine che si chiama TWIG che con un azione di contrassegno in punti specifici della pagina ci consente di mettere in moto delle operazioni dinamiche. Vediamo in node questo meccanismo come funziona, anche qui in rete c’è molto materiale da tirar fuori ed esplorare come https://www.nodeacademy.it/cose-ejs-template-engine-express-js/ per esempio. Abbiamo un modulo che fa questo in node che mustache-express che andrà richiamato nel solito modo dopo quello express: const mustacheExpress = require (‘mustache-express’); Attraverso un sistema dinamico di instradamento dei dati nella directory view che di volta in volta riceve il parametro con i suoi esclusivi contenuti, avremo una visualizzazione diversa e nell’ html sarà solo sufficiente indicare la route per marcare le zone di volta in volta che si riempiranno in base alle scelte dell utente. Più difficile da descrivere che a vedersi, diamo un occhiata al file server.js per vedere a video il risultato seguente:

const express = require(‘express’);
const mustacheExpress = require(‘mustache-express’);
const app = express();
app.engine(‘html’, mustacheExpress());

app.set(‘view engine’, ‘html’);
app.set(‘views’, __dirname + ‘/views’);
app.use(‘/assets’, express.static(‘assets’));

const index = {
title: “Home”,
articleParas: [{text: “Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum ipsum augue, gravida nec lacinia condimentum, imperdiet at nunc. Curabitur eget elementum tortor, ornare mattis ligula. Vestibulum pulvinar nunc eget urna vestibulum convallis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis a varius neque, at laoreet nisi. Vestibulum maximus lobortis libero non porttitor. Integer consequat nec erat at varius. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.”},
{text: “Maecenas in consectetur lorem, sit amet gravida orci. Maecenas laoreet lacus et enim aliquam, nec dictum ex sollicitudin. Ut sed eleifend justo. Etiam facilisis nunc quis nisl congue, quis dictum nisl volutpat. Suspendisse sollicitudin tristique diam hendrerit suscipit. Praesent sodales ligula at felis pharetra, nec dapibus velit porta. Etiam nec lectus in sapien cursus rutrum. Nam tristique est et felis consequat pharetra. Vestibulum vitae maximus est. Aliquam erat volutpat.”},
{text: “Vestibulum non dui pretium, finibus ante quis, luctus sapien. Maecenas a venenatis sem. Sed lacinia justo ut auctor porta. Nulla quis ultrices urna, quis tempor magna. Pellentesque at dui eget augue maximus convallis. Donec vel cursus lorem. Donec lorem neque, aliquam ut facilisis id, tincidunt eget ligula. Vestibulum eu consectetur felis.”}]
};

const about = {
title: “About Us”,
articleParas: [{text: “Maecenas in consectetur lorem, sit amet gravida orci. Maecenas laoreet lacus et enim aliquam, nec dictum ex sollicitudin. Ut sed eleifend justo. Etiam facilisis nunc quis nisl congue, quis dictum nisl volutpat. Suspendisse sollicitudin tristique diam hendrerit suscipit. Praesent sodales ligula at felis pharetra, nec dapibus velit porta. Etiam nec lectus in sapien cursus rutrum. Nam tristique est et felis consequat pharetra. Vestibulum vitae maximus est. Aliquam erat volutpat.”},
{text: “Vestibulum non dui pretium, finibus ante quis, luctus sapien. Maecenas a venenatis sem. Sed lacinia justo ut auctor porta. Nulla quis ultrices urna, quis tempor magna. Pellentesque at dui eget augue maximus convallis. Donec vel cursus lorem. Donec lorem neque, aliquam ut facilisis id, tincidunt eget ligula. Vestibulum eu consectetur felis.”},
{text: “Duis quis neque consequat, pellentesque libero quis, sagittis arcu. Sed tincidunt in ipsum non laoreet. Proin id blandit metus, eu semper orci. Vivamus eu fringilla leo. Quisque et faucibus felis. Pellentesque tincidunt purus ut elit malesuada, quis tristique sem hendrerit. Nunc dapibus vulputate sapien eget maximus. In porta, sem sit amet commodo placerat, neque sapien tempor nulla, sit amet pretium velit turpis nec nulla. Etiam porta pretium turpis, sed dignissim nisl scelerisque ac. Phasellus sed efficitur justo, ac egestas ex. Vestibulum interdum fringilla magna, quis maximus dolor pulvinar nec. Vestibulum posuere sem nulla, ac condimentum tortor imperdiet et. Mauris viverra ultricies justo, in interdum lacus feugiat rutrum. Nulla hendrerit vel tortor non gravida. Praesent eu ultricies mi.”}]
};

const news = {
title: “Latest News”,
articleParas: [{text: “Vestibulum non dui pretium, finibus ante quis, luctus sapien. Maecenas a venenatis sem. Sed lacinia justo ut auctor porta. Nulla quis ultrices urna, quis tempor magna. Pellentesque at dui eget augue maximus convallis. Donec vel cursus lorem. Donec lorem neque, aliquam ut facilisis id, tincidunt eget ligula. Vestibulum eu consectetur felis.”},
{text: “Duis quis neque consequat, pellentesque libero quis, sagittis arcu. Sed tincidunt in ipsum non laoreet. Proin id blandit metus, eu semper orci. Vivamus eu fringilla leo. Quisque et faucibus felis. Pellentesque tincidunt purus ut elit malesuada, quis tristique sem hendrerit. Nunc dapibus vulputate sapien eget maximus. In porta, sem sit amet commodo placerat, neque sapien tempor nulla, sit amet pretium velit turpis nec nulla. Etiam porta pretium turpis, sed dignissim nisl scelerisque ac. Phasellus sed efficitur justo, ac egestas ex. Vestibulum interdum fringilla magna, quis maximus dolor pulvinar nec. Vestibulum posuere sem nulla, ac condimentum tortor imperdiet et. Mauris viverra ultricies justo, in interdum lacus feugiat rutrum. Nulla hendrerit vel tortor non gravida. Praesent eu ultricies mi.”},
{text: “Donec aliquam urna sed eros viverra maximus. Suspendisse vitae pellentesque lorem. Aenean nec accumsan dolor. Proin velit risus, consectetur sit amet lacus lacinia, finibus fermentum nibh. Duis consectetur tempus lorem eu rhoncus. Sed dictum erat vel ligula consequat, eget ornare sem scelerisque. Nulla eu magna id enim interdum blandit vitae non massa. Integer vehicula dapibus ligula, at auctor lectus volutpat sit amet. Nullam vulputate arcu vitae turpis iaculis varius. Mauris ac elit ac libero pharetra suscipit.”}]
};

const ourPeople = {
title: “Our People”,
articleParas: [{text: “Duis quis neque consequat, pellentesque libero quis, sagittis arcu. Sed tincidunt in ipsum non laoreet. Proin id blandit metus, eu semper orci. Vivamus eu fringilla leo. Quisque et faucibus felis. Pellentesque tincidunt purus ut elit malesuada, quis tristique sem hendrerit. Nunc dapibus vulputate sapien eget maximus. In porta, sem sit amet commodo placerat, neque sapien tempor nulla, sit amet pretium velit turpis nec nulla. Etiam porta pretium turpis, sed dignissim nisl scelerisque ac. Phasellus sed efficitur justo, ac egestas ex. Vestibulum interdum fringilla magna, quis maximus dolor pulvinar nec. Vestibulum posuere sem nulla, ac condimentum tortor imperdiet et. Mauris viverra ultricies justo, in interdum lacus feugiat rutrum. Nulla hendrerit vel tortor non gravida. Praesent eu ultricies mi.”},
{text: “Donec aliquam urna sed eros viverra maximus. Suspendisse vitae pellentesque lorem. Aenean nec accumsan dolor. Proin velit risus, consectetur sit amet lacus lacinia, finibus fermentum nibh. Duis consectetur tempus lorem eu rhoncus. Sed dictum erat vel ligula consequat, eget ornare sem scelerisque. Nulla eu magna id enim interdum blandit vitae non massa. Integer vehicula dapibus ligula, at auctor lectus volutpat sit amet. Nullam vulputate arcu vitae turpis iaculis varius. Mauris ac elit ac libero pharetra suscipit.”},
{text: “Pellentesque risus nisi, malesuada at tempor in, cursus vitae nibh. Maecenas vitae sollicitudin libero, eget blandit ex. Fusce vitae purus quis dolor pulvinar tempus. Nullam fermentum efficitur massa. Nullam mattis augue ac feugiat posuere. Curabitur eget pellentesque nisi. Nunc semper turpis non blandit pretium. Etiam mollis libero at mi egestas faucibus. Fusce in leo vel augue faucibus bibendum ut non magna. Nunc ut nunc vitae nulla placerat placerat. Maecenas tincidunt, urna et euismod imperdiet, dui purus tempus odio, vel posuere arcu odio non risus.”}]
};

const careers = {
title: “Careers”,
articleParas: [{text: “Donec aliquam urna sed eros viverra maximus. Suspendisse vitae pellentesque lorem. Aenean nec accumsan dolor. Proin velit risus, consectetur sit amet lacus lacinia, finibus fermentum nibh. Duis consectetur tempus lorem eu rhoncus. Sed dictum erat vel ligula consequat, eget ornare sem scelerisque. Nulla eu magna id enim interdum blandit vitae non massa. Integer vehicula dapibus ligula, at auctor lectus volutpat sit amet. Nullam vulputate arcu vitae turpis iaculis varius. Mauris ac elit ac libero pharetra suscipit.”},
{text: “Pellentesque risus nisi, malesuada at tempor in, cursus vitae nibh. Maecenas vitae sollicitudin libero, eget blandit ex. Fusce vitae purus quis dolor pulvinar tempus. Nullam fermentum efficitur massa. Nullam mattis augue ac feugiat posuere. Curabitur eget pellentesque nisi. Nunc semper turpis non blandit pretium. Etiam mollis libero at mi egestas faucibus. Fusce in leo vel augue faucibus bibendum ut non magna. Nunc ut nunc vitae nulla placerat placerat. Maecenas tincidunt, urna et euismod imperdiet, dui purus tempus odio, vel posuere arcu odio non risus.”},
{text: “Praesent auctor nunc sed dui consequat scelerisque. Proin vestibulum tellus fringilla dapibus scelerisque. Integer eu blandit est. Sed eget libero varius, porttitor risus in, luctus quam. Integer vel mi nec tellus convallis elementum. Vestibulum consequat non nulla non iaculis. Nunc facilisis blandit ante, at vulputate ligula lobortis eget. Nam vulputate tortor sodales, ornare justo sed, molestie enim.”}]
};

app.get(‘/’, (req, res) => {
res.render(‘index’, index);
});

app.get(‘/about’, (req, res) => {
res.render(‘index’, about);
});

app.get(‘/news’, (req, res) => {
res.render(‘index’, news);
});

app.get(‘/our-people’, (req, res) => {
res.render(‘index’, ourPeople);
});

app.get(‘/careers’, (req, res) => {
res.render(‘index’, careers);
});

app.listen(8080);

vediamo anche nella pagina statica html nella parte di accoglienza contenuti come sono tracciate queste route o instradamenti, con parametri in ricezione mandati tramite variabili get:

<ul class=”navbar-nav mx-auto”>
<li class=”nav-item active”>
<a class=”nav-link” href=”/”>Home</a>
</li>
<li class=”nav-item”>
<a class=”nav-link” href=”/about”>About</a>
</li>
<li class=”nav-item”>
<a class=”nav-link” href=”/news” tabindex=”-1″ aria-disabled=”true”>News</a>
</li>
<li class=”nav-item”>
<a class=”nav-link” href=”/our-people” tabindex=”-1″ aria-disabled=”true”>Our People</a>
</li>
<li class=”nav-item”>
<a class=”nav-link” href=”/careers” tabindex=”-1″ aria-disabled=”true”>Careers</a>
</li>
</ul>

CONCLUSIONI: Node JS è ostico ma non temibile come l’invasione degli ultracorpi (Invasion of the Body Snatchers), film del 1956 diretto da Don Siegel, il cui soggetto è tratto dall’omonimo romanzo di fantascienza di Jack Finney del 1955. Approfondiamo da Wiki: film girato a basso costo e in bianco e nero, è in seguito divenuto un film cult ed è ricordato come uno dei più celebri film di fantascienza degli anni cinquanta e citato come uno dei capolavori del cinema fantascientifico. Ha avuto tre remake, Terrore dallo spazio profondo (del 1978, vedi contenuto scandagliato da Umbriaway Consulting https://umbriawaycultura.wordpress.com/2020/05/15/node-terrore-dallo-spazio-profondo-prima-puntata/ ), Ultracorpi – L’invasione continua (1993) e Invasion (2007). Nel 1994 il film è stato scelto per essere conservato nel National Film Registry della Biblioteca del Congresso degli Stati Uniti. Nel 2019 è stato proiettato al Cinemazero di Pordenone nella pellicola 50 mm. Il problema di fondo è acquisire una certa manualità da tastiera con la vecchia finestra dos di window e anche quello di capire la logica generale che permette a node di gestire i più svariati problemi di struttura dei file, di inizializzazione, di dipendenze, di acquisizione e gestione moduli, di modellazione script. Qui abbiamo riscontrato anche una certa difficoltà a inizializzare MONGODB perchè la procedura indicata sopra non è semplice per un profano. Ricordiamoci sempre che per far funzionare queste tecnologie con le nostre web app abbiamo bisogno di trasportare tutto esternamente su server dedicati che offrono questi servizi. Possiamo capire node come un gigantesco armadio pieno di cassetti e oggetti, ciascuno dei quali risolve un problema specifico. Come viene gestito il traffico HTTP (HyperText Transfer Protocol, protocollo di trasferimento di un ipertesto)? Quali moduli devo installare per gestire le sessioni? Come gestisco la comunicazione rapida client server ipotizzando di aver creato un nuovo social media tipo twitter? Come posso memorizzare i dati? Come posso migliorare la sciurezza sull’ header HTTP? Come posso gestire meglio la separazione di logica javascript con la parte statica che è priva di programmazione dinamica? Node è molto veloce e potente, con qualche rapido comando consente di implementare subito i mattoni che servono per mettere in piedi un edificio. Ma occorre molta pratica e molto lavoro sporco! Quello che ci ha sorpreso di più in questo percorso è stata la gestione dei dati: ossia Mongo non ci fa preparare prima i campi di accoglienza  come succede con PHP e mysql.

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...