Go Academy · Lektion

Sända meddelanden

Skicka till många klienter

Lektion 3 av 413 steg

Sända meddelanden är en gratis lektion i Go Academy på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Go Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Go Academy innehåller totalt 4 lektioner.

Skicka till många klienter

Chattrum och liveflöden behöver skicka ett enda meddelande till varje ansluten klient. Eftersom varje WebSocket bara tillåter en skrivare behöver du ett samordningsmönster: hubben.

Hub-mönstret

En hubb är en central goroutine som äger uppsättningen klienter och en broadcastkanal. Klienter registreras och avregistreras, och hubben sprider meddelanden till dem. Ingen delad map används direkt av flera goroutines.

Hubbens datastrukturer

Hubben innehåller:

  • En uppsättning klienter (map[*Client]bool)
  • En broadcast-kanal med meddelanden
  • Kanalerna register och unregister
type Hub struct {
    clients    map[*Client]bool
    broadcast  chan []byte
    register   chan *Client
    unregister chan *Client
}

Hubbens körloop

En enda Run-goroutine väljer mellan kanalerna. Eftersom bara denna goroutine ändrar map:en behövs ingen 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
            }
        }
    }
}

Separat sändningskanal per klient

Varje klient har en buffrad send chan []byte. Hubben skriver till den, och en dedikerad skrivargoroutine tömmer den till socketen. På så sätt följs regeln om en enda skrivare.

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

Skrivargoroutinen

Varje klient kör en writePump som itererar över send och skriver till socketen. När kanalen stängs skickar den en close-ram.

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

Undvika långsamma klienter

Om en klient är långsam fylls dess buffrade send-kanal. En vanlig policy är att koppla från klienten om bufferten är full i stället för att blockera hela hubben.

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

Varför kanaler framför mutexar

Gos motto är: "dela minne genom kommunikation". Genom att samla alla ändringar i en enda goroutine via kanaler undviker du race conditions i klientmap:en utan explicit låsning.

Broadcasta ett meddelande

Vilken handler som helst kan broadcaste genom att skicka på hubbens kanal; hubben sprider sedan meddelandet till alla registrerade klienter.

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

Riktat kontra broadcast

För rum eller direktmeddelanden kan du lagra klienter med rums- eller användar-ID som nyckel och bara iterera över den relevanta delmängden i stället för alla klienter. Då förblir en chatt med många rum effektiv.

Körbart: Fan-out med kanaler

Detta fristående program modellerar hur en hubb sprider ett meddelande till flera klientkanaler med endast standardbiblioteket och goroutines.

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()
}

Snabbtest

Testa dina kunskaper om broadcast.

Sammanfattning

Du har lärt dig att broadcaste till många klienter:

  • Hubbens goroutine äger klientuppsättningen och en broadcastkanal
  • Varje klient har en buffrad send-kanal som töms av en skrivargoroutine
  • Detta följer regeln om en skrivare per anslutning
  • Koppla från långsamma klienter så att hubben förblir responsiv
Gratis att börja

Lär dig Go med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
51
Lektioner
203

Vanliga frågor

Är lektionen ”Sända meddelanden” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Go Academy, inklusive ”Sända meddelanden”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Go Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Sända meddelanden”?

Skicka till många klienter Ni övar på Go Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Go Academy?

Du behöver inga förkunskaper. Utbildningen i Go Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Sända meddelanden”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Go Academy-lektionen?

Ja. Varje Go Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Grunderna i WebSocket
  2. Använda gorilla/websocket
  3. Sända meddelanden
  4. Anslutningshantering
← Tillbaka till Go Academy