====== Idee su come organizzare il codice di un'applicazione spa che faccia uso di websocket ======
Autore: **//Fabio Di Matteo//** \\ Ultima revisione: **// 23/09/2026 15:31 //** // //
L'idea in se è semplice. Costruire unapplicazione a pagina singola che permetta di scambiare dati (pacchetti json) col server tramite una connessione di tipo websocket e non una classica connessione http stateless.
===== Perchè? =====
- Avendo una connessione websocket il server puo' decidere a suo "piacimento" quando inviare dati al client;
- Lo scambio dei dati avviene a una velocità piu' elevata e senza l'overhead di http;
===== Perchè no? =====
- Bisogna implementare un servizio di routing dei pacchetti json sia nel server che nel client;
===== Idea =====
Puo' essere utile farsi un'idea con questo codice C++ funzionante [[https://www.freemedialab.org/code/project.php?p=ffmpeg_web_local_app|progetto d'esempio]]. Questo esempio fa uso del framework Crow.
==== Server ====
Nell'esempio si crea un' insolita app desktop che usa il browser web per mostrare la sua interfaccia grafica, non è pensata per uso in rete, resta in ascolto su localhost. Le pagine hanno un pin casuale per garantire un minimo di sicurezza interna.
Il server è un server websocket, possiede una funzione che fa da router dei pacchetti json in arrivo dal client e alcune funzioni che fanno da helper per la creazione di pacchetti json da inviare al client.
Esempio di router lato server:
void router(crow::websocket::connection& conn, const std::string& data,const std::string& pin)
{
auto json = crow::json::load(data);
std::string op=json["op"].s();
std::string file=json["file"].s();
const std::string npin =json["pin"].s();
disable(conn,pin, "btn_convert");
if (npin!=pin)
{
fmt::println("Invalid pin");
write_html(conn,pin, "output", "Your pin is wrong!");
return;
}
if (op=="h264")
{
std::string msg = fmt::format("Si richiede di convertire il file {} in {}",file,op);
write_html(conn,pin, "output", msg);
}else{
write_html(conn,pin,"output","Error! The request operation is wrong!");
}
enable(conn,pin, "btn_convert");
}
**Esempio di funzioni helper**
void disable(crow::websocket::connection& c, const std::string& pin ,const std::string& id)
{
crow::json::wvalue json;
json["action"]= "disable";
json["id"]= id;
json["pin"]=pin;
c.send_text(json.dump());
}
void enable(crow::websocket::connection& c, const std::string& pin ,const std::string& id)
{
crow::json::wvalue json;
json["action"]= "enable";
json["id"]= id;
json["pin"]=pin;
c.send_text(json.dump());
}
void write_html(crow::websocket::connection& c, const std::string& pin ,const std::string& id, const std::string& html)
{
crow::json::wvalue json;
json["action"]= "write_html";
json["id"]= id;
json["html"]=html;
json["pin"]=pin;
c.send_text(json.dump());
}