0Pricing
Go Academy · Lezione

Trasmettere messaggi

Inviare a molti client

Trasmettere messaggi è una lezione Go Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Go Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Go Academy include 4 lezioni in totale.

Inviare a molti client

Le chat room e i feed in tempo reale devono inviare un singolo messaggio a ogni client connesso. Poiché ogni WebSocket consente un solo scrittore, è necessario un modello di coordinamento: l'hub.

Il modello hub

Un hub è una goroutine centrale che gestisce l'insieme dei client e un canale broadcast. I client si registrano e si scollegano, mentre l'hub distribuisce i messaggi a tutti. Nessuna mappa condivisa viene modificata direttamente da più goroutine.

Strutture dati dell'hub

L'hub contiene:

  • Un insieme di client (map[*Client]bool)
  • Un canale broadcast di messaggi
  • I canali register e unregister
type Hub struct {
    clients    map[*Client]bool
    broadcast  chan []byte
    register   chan *Client
    unregister chan *Client
}

Il ciclo di esecuzione dell'hub

Una singola goroutine Run esegue una selezione sui canali. Poiché solo questa goroutine modifica la mappa, non è necessario alcun mutex.

func (h *Hub) Run() {
    for {
        select {
        case c := <-h.register:
            h.clients[c] = true
        case c := <-h.unregister:
            delete(h.clients, c)
            close(c.send)
        case msg := <-h.broadcast:
            for c := range h.clients {
                c.send <- msg
            }
        }
    }
}

Canale di invio per client

Ogni client dispone di un send chan []byte con buffer. L'hub vi scrive, mentre una goroutine di scrittura dedicata ne preleva i valori e li invia al socket. In questo modo si rispetta la regola di un solo scrittore.

type Client struct {
    conn *websocket.Conn
    send chan []byte
}

La goroutine di scrittura

Ogni client esegue un writePump che scorre send e scrive nel socket. Quando il canale viene chiuso, invia un frame di chiusura.

func (c *Client) writePump() {
    for msg := range c.send {
        c.conn.WriteMessage(websocket.TextMessage, msg)
    }
}

Evitare i client lenti

Se un client è lento, il suo send con buffer si riempie. Una politica comune consiste nel disconnettere il client quando il buffer è pieno, invece di bloccare l'intero hub.

select {
case c.send <- msg:
default:
    close(c.send)
    delete(h.clients, c)
}

Perché usare i canali invece dei mutex

Il motto di Go è: "condividere la memoria comunicando". Convogliare tutte le modifiche attraverso un'unica goroutine tramite i canali evita le race condition sulla mappa dei client senza ricorrere a un locking esplicito.

Trasmettere un messaggio

Qualsiasi handler può eseguire un broadcast inviando un messaggio sul canale dell'hub; l'hub lo distribuisce a tutti i client registrati.

hub.broadcast <- []byte("server announcement")

Invio mirato e broadcast

Per le room o i messaggi diretti, memorizzi i client associandoli all'ID della room o dell'utente e iteri solo sul sottoinsieme pertinente, invece di esaminare tutti i client. In questo modo una chat con molte room rimane efficiente.

Eseguibile: distribuzione a ventaglio con i canali

Questo programma autonomo modella un hub che distribuisce un messaggio a più canali client utilizzando solo la libreria standard e le goroutine.

package main

import (
    "fmt"
    "sync"
)

func main() {
    clients := []chan string{make(chan string, 1), make(chan string, 1), make(chan string, 1)}
    msg := "hello all"
    for _, c := range clients {
        c <- msg // fan-out
    }
    var wg sync.WaitGroup
    for i, c := range clients {
        wg.Add(1)
        go func(id int, ch chan string) {
            defer wg.Done()
            fmt.Printf("client %d got: %s\n", id, <-ch)
        }(i, c)
    }
    wg.Wait()
}

Verifica rapida

Verifichi la propria comprensione del broadcasting.

Riepilogo

Ha imparato a trasmettere a molti client:

  • La goroutine dell'hub gestisce l'insieme dei client e un canale broadcast
  • Ogni client dispone di un canale send con buffer, svuotato da una goroutine di scrittura
  • In questo modo si rispetta la regola di un solo scrittore per connessione
  • Disconnetta i client lenti per mantenere reattivo l'hub

Domande Frequenti

La lezione «Trasmettere messaggi» è gratuita?

Sì — il testo completo di «Trasmettere messaggi» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Go Academy, passa a CoddyKit PRO. Il corso Go Academy include 4 lezioni in totale.

Cosa imparerò in «Trasmettere messaggi»?

Inviare a molti client Eserciti Go Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Go Academy?

Non è richiesta alcuna esperienza precedente. Go Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Trasmettere messaggi»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Go Academy?

Sì. Ogni lezione Go Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Nozioni di base su WebSocket
  2. Usare gorilla/websocket
  3. Trasmettere messaggi
  4. Gestione delle connessioni
← Torna a Go Academy