Benvenuto alla quinta lezione della nostra guida su Laravel e WebSocket! In questa lezione, ci concentreremo su un aspetto cruciale per le applicazioni moderne: la comunicazione dispositivo-server. Dopo aver configurato con successo il nostro ambiente WebSocket e aver appreso come monitorare e gestire le connessioni in tempo reale, è ora di esplorare come i dispositivi client possono comunicare efficacemente con il server.
Comunicazione dispositivo-server con Laravel
La comunicazione dispositivo-server è fondamentale per molte funzionalità avanzate nelle applicazioni web, come chat in tempo reale, notifiche istantanee, aggiornamenti live e molto altro. Questa lezione ti guiderà attraverso i principi e le pratiche migliori per implementare una comunicazione efficiente e sicura tra i dispositivi client e il server utilizzando WebSocket.
Inizieremo approfondendo come i dispositivi client possono stabilire una connessione WebSocket con il server, mantenendo una comunicazione bidirezionale aperta. Vedremo come gestire le varie interazioni tra client e server, garantendo che i messaggi vengano trasmessi e ricevuti correttamente.
Successivamente, implementeremo un esempio pratico in cui un dispositivo invia dati al server e riceve risposte in tempo reale. Questo ci permetterà di comprendere meglio come utilizzare gli eventi WebSocket per creare un flusso di comunicazione continuo ed efficiente.
Inoltre, esploreremo le tecniche per gestire la sicurezza e l'autenticazione nella comunicazione, assicurando che solo i dispositivi autorizzati possano connettersi e scambiare dati con il server.
Concluderemo la lezione con una panoramica delle best practice per ottimizzare le performance della comunicazione WebSocket, garantendo che la tua applicazione rimanga reattiva e scalabile anche con un elevato numero di connessioni.
Preparati a portare le tue competenze su Laravel e WebSocket al prossimo livello, scoprendo come implementare una comunicazione dispositivo-server efficace e sicura. Iniziamo!
Crea la view con Laravel
Laravel crea per noi una view di default in resources\views\welcome.blade.php
:
Questo file lo puoi eliminare, non serve al nostro scopo, per poi crearne uno nuovo. Chiamalo ad esempio chat-appt.php
. Ricordati di aggiornare anche la rotta in web.php
:
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', function () {
return view('chat-app');
});
Apri la view
chat-app
e modifica come di seguito:
<div id="app">
<div class="container">
<h1 class="text-center mt-4">Laravel WebSocket</h1>
<div class="card mt-4">
<div class="card-header p-2">
<div class="col-lg-2 col-md-3 col-sm-12 mt-2 p-0">
<label>Name</label>
</div>
<div class="col-lg-1 col-md-2 col-sm-12 mt-2 p-0">
<button class="mr-2 btn btn-sm btn-primary w-100" type="button">
Connect
</button>
<button class="mr-2 btn btn-sm btn-danger w-100" type="button">
Disconnect
</button>
</div>
</div>
<div class="card-body">
<h4 class="mt-4">Message</h4>
</div>
</div>
</div>
</div>
<script>
new Vue({
el: "#app",
data: {
connected: false,
name: null,
message: [
{
message: "Your message",
name: "Lucio",
time: 2012
}
]
},
methods: {
connect() {
this.connected = true;
console.log("Connected"); // Per debug
// Aggiungi qui la logica per la connessione WebSocket
},
disconnect() {
this.connected = false;
console.log("Disconnected"); // Per debug
// Aggiungi qui la logica per la disconnessione WebSocket
}
}
});
</script>
Di seguito la spiegazione del codice.
Struttura HTML e intestazione
- Definisce che il documento è di tipo HTML.
- Specifica che la lingua della pagina è l'inglese.
- Contiene metadati, collegamenti a fogli di stile e script.
- Imposta l'encoding dei caratteri a UTF-8.
- Imposta la larghezza della viewport e il livello di zoom iniziale.
- Titolo della pagina visualizzato nella scheda del browser.
- Script e stili importati da CDN per jQuery, Pusher (per WebSocket), Vue.js e Bootstrap per il layout e lo stile della pagina.
Corpo della Pagina HTML
<div id="app">
<div class="container">
<h1 class="text-center mt-4">Laravel WebSocket</h1>
<div class="card mt-4">
<div class="card-header p-2">
<div class="col-lg-2 col-md-3 col-sm-12 mt-2 p-0">
<label>Name</label>
</div>
<div class="col-lg-1 col-md-2 col-sm-12 mt-2 p-0">
<button class="mr-2 btn btn-sm btn-primary w-100" type="button">
Connect
</button>
<button class="mr-2 btn btn-sm btn-danger w-100" type="button">
Disconnect
</button>
</div>
</div>
<div class="card-body">
<h4 class="mt-4">Message</h4>
</div>
</div>
</div>
</div>
<div id="app">..</div>
: elemento radice dell'applicazione Vue.js.<div class="container">..</div>
: utilizzato per centrare il contenuto nella pagina.-
<h1 class="text-center mt-4">Laravel WebSocket</h1>
: intestazione principale centrata.
<div class="card mt-4">..</div>
: contenitore per il modulo e i messaggi.<div class="card-header p-2">..</div>
: intestazione della card con il form per il nome e il pulsante di connessione.
Troviamo poi:
- la gestione dell'evento di
submit
del form, prevenendo il comportamento predefinito. - un campo input controllato da Vue.js tramite
v-model
. - I pulsanti per connettersi o disconnettersi, mostrati in base allo stato di
connected
.
Script JavaScript (Vue.js)
<script>
new Vue({
el: "#app",
data: {
connected: false,
name: null
},
methods: {
connect() {
this.connected = true;
console.log("Connected"); // Per debug
// Aggiungi qui la logica per la connessione WebSocket
this.message = [
{
message: "Your message",
name: "Lucio",
time: 2012
}
];
},
disconnect() {
this.connected = false;
console.log("Disconnected"); // Per debug
// Aggiungi qui la logica per la disconnessione WebSocket
}
}
});
</script>
- Inizia un'istanza Vue.js con
new Vue({...})
. el: "#app"
: collega Vue all'elemento con id "app
" nel DOM.data
: contiene i dati dell'applicazione Vue.connected
: booleano per tracciare lo stato di connessione.name
: stringa per memorizzare il nome inserito dall'utente.methods
: contiene i metodi che gestiscono l'interazione dell'utente con l'interfaccia.connect()
: impostaconnected
sutrue
quando l'utente si connette.disconnect()
: impostaconnected
sufalse
quando l'utente si disconnette.- I
console.log()
vengono utilizzati per il debug per mostrare messaggi nella console del browser.
Al momento gestiamo un semplice form per inserire un nome e due pulsanti per connettersi o disconnettersi. Il codice Vue.js gestisce lo stato di connessione e disconnessione e può essere esteso per includere la logica per le WebSocket o altre interazioni dinamiche con il server.
Aggiungere sezioni
Continuiamo ad implementare il nostro frontend dove affronteremo la gestione dei messaggi ricevuti e l'invio di nuovi messaggi. Riprendiamo il codice e scriviamo come di seguito:
<div class="col-12 bg-light pt-2 pb-2 mt-3">
<p class="p-0 m-0 ps-2 pe-2">({{ message.time }}) <b>{{ message.name }}</b> {{ message.message }}</p>
</div>
<h4 class="mt-4">Message</h4>
<div class="row mt-2">
<div class="col-12 text-white">
<div class="bg-danger p-2 mb-2">
<p class="p-0 m-0"><b>Error:</b> {{ error }}</p>
</div>
</div>
</div>
Sezione dei messaggi ricevuti (incomingMessages):
- Utilizza un
div
con classebg-light
per creare un background grigio chiaro. - Utilizza
v-for="(message, index)
inincomingMessages
per iterare attraverso gli elementi dell'arrayincomingMessages
e mostrare ogni messaggio. - Mostra il timestamp del messaggio
({{ message.time }})
, il nome dell'autore del messaggio<b>{{ message.name }}</b>
, e il contenuto del messaggio{{ message.message }}
.
Sezione per inviare un nuovo messaggio:
- Mostra un titolo "Message" (<h4 class="mt-4">Message</h4>) sopra il form per l'invio del messaggio.
- Utilizza un form con
@submit.prevent="sendMessage"
per gestire l'invio del messaggio. - Mostra un eventuale messaggio di errore in un
div
rosso (bg-danger
) solo seerror
è definito (v-if="error"
). - Visualizza il messaggio di errore specificato in
{{ error }}
.
Questi aggiornamenti consentono all'utente di vedere i messaggi ricevuti e di inviare nuovi messaggi attraverso il form fornito.
Correzione per il messaggio di errore
Apri il browser e punta all'applicazione:
Come puoi notare si vede il messaggio d'errore e non va bene per cui riapri l'IDE e modifica:
formError: false,
<div class="row mt-2">
<div class="col-12 text-white">
<div class="bg-danger p-2 mb-2">
<p class="p-0 m-0"><b>Error:</b> Invalid message</p>
</div>
</div>
<div class="col-12">
<div class="form-group">
<textarea class="form-control" rows="3"></textarea>
</div>
</div>
</div>
<div class="row text-right mt-2">
<div class="col-lg-10"></div>
<div class="col-lg-2">
<button class="btn btn-small btn-success w-100" type="button">Send Event</button>
</div>
</div>
quindi:
<script>
new Vue({
el: "#app",
data: {
connected: false,
name: null,
formError: false,
incomingMessages: [
{
message: "Your message",
name: "Lucio",
time: 2012
}
],
message: null
},
methods: {
connect() {
this.connected = true;
console.log("Connected"); // Per debug
// Aggiungi qui la logica per la connessione WebSocket
},
disconnect() {
this.connected = false;
console.log("Disconnected"); // Per debug
// Aggiungi qui la logica per la disconnessione WebSocket
}
}
});
</script>
Conclusione
In questo articolo, abbiamo focalizzato l'attenzione sulla gestione dei messaggi ricevuti e sull'invio di nuovi messaggi in tempo reale. Utilizzando Vue.js, abbiamo creato un'interfaccia utente interattiva che consente agli utenti di visualizzare dinamicamente i messaggi ricevuti e di inviare nuovi messaggi senza ricaricare la pagina.
Abbiamo visto come integrare Vue.js per iterare attraverso gli array di messaggi e visualizzare ogni messaggio con il suo timestamp, il nome dell'autore e il contenuto. Inoltre, abbiamo implementato un form per l'invio dei messaggi, gestendo gli eventi di submit
per migliorare l'esperienza utente e fornendo feedback immediato in caso di errori.
Nel prossimo articolo, concluderemo ed esploreremo ulteriori avanzamenti, inclusi metodi per migliorare la sicurezza e l'autenticazione delle comunicazioni WebSocket, ottimizzando le prestazioni per gestire carichi elevati di traffico e implementando funzionalità avanzate come la gestione dei thread di chat e le notifiche push in tempo reale.