0Pricing
Go Academy · Lektion

Nachrichten verteilen

An viele Clients senden

Nachrichten verteilen ist eine kostenlose Go Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Go Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Go Academy-Kurs umfasst insgesamt 4 Lektionen.

An viele Clients senden

Chatrooms und Live-Feeds müssen eine einzelne Nachricht an jeden verbundenen Client senden. Da jeder WebSocket nur einen Writer erlaubt, benötigen Sie ein Koordinationsmuster: den Hub.

Das Hub-Muster

Ein Hub ist eine zentrale Goroutine, die die Menge der Clients und einen Broadcast-Kanal verwaltet. Clients werden registriert und abgemeldet, und der Hub verteilt Nachrichten an alle. Keine gemeinsame Map wird direkt von mehreren Goroutinen verwendet.

Datenstrukturen des Hubs

Der Hub enthält:

  • Eine Menge von Clients (map[*Client]bool)
  • Einen broadcast-Kanal für Nachrichten
  • register- und unregister-Kanäle
type Hub struct {
    clients    map[*Client]bool
    broadcast  chan []byte
    register   chan *Client
    unregister chan *Client
}

Die Run-Schleife des Hubs

Eine einzelne Run-Goroutine wartet mit select auf den Kanälen. Da nur diese Goroutine die Map verändert, ist kein Mutex erforderlich.

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

Sendekanal pro Client

Jeder Client verfügt über einen gepufferten send chan []byte. Der Hub schreibt in diesen Kanal, und eine dedizierte Writer-Goroutine liest daraus und schreibt in den Socket. Dadurch wird die Regel für einen Writer eingehalten.

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

Die Writer-Goroutine

Jeder Client führt einen writePump aus, der über send iteriert und in den Socket schreibt. Wird der Kanal geschlossen, sendet die Goroutine einen Close-Frame.

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

Langsame Clients vermeiden

Wenn ein Client langsam ist, füllt sich sein gepufferter send-Kanal. Eine gängige Strategie besteht darin, bei vollem Puffer den Client zu entfernen, statt den gesamten Hub zu blockieren.

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

Warum Kanäle statt Mutexes

Gos Motto lautet: „Speicher durch Kommunikation teilen.“ Wenn alle Änderungen über Kanäle durch eine einzige Goroutine geleitet werden, lassen sich Race-Bedingungen bei der Client-Map ohne explizite Sperren vermeiden.

Eine Nachricht broadcasten

Jeder Handler kann eine Nachricht über den Hub-Kanal broadcasten. Der Hub verteilt sie dann an jeden registrierten Client.

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

Gezielt senden oder broadcasten

Speichern Sie für Räume oder Direktnachrichten die Clients nach Raum- oder Benutzer-ID gruppiert und durchlaufen Sie nur die relevante Teilmenge statt aller Clients. So bleibt ein Chat mit vielen Räumen effizient.

Ausführbar: Fan-out mit Kanälen

Dieses eigenständige Programm bildet ab, wie ein Hub eine Nachricht mithilfe ausschließlich der Standardbibliothek und von Goroutinen auf mehrere Client-Kanäle verteilt.

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

Kurztest

Testen Sie Ihr Verständnis des Broadcastings.

Zusammenfassung

Sie haben gelernt, an viele Clients zu broadcasten:

  • Die Hub-Goroutine verwaltet die Client-Menge und einen Broadcast-Kanal
  • Jeder Client verfügt über einen gepufferten Sendekanal, aus dem eine Writer-Goroutine liest
  • Dadurch wird die Regel für einen Writer pro Verbindung eingehalten
  • Entfernen Sie langsame Clients, damit der Hub reaktionsfähig bleibt

Häufig gestellte Fragen

Ist die Lektion „Nachrichten verteilen“ kostenlos?

Ja — der vollständige Text von „Nachrichten verteilen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Go Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Go Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Nachrichten verteilen“?

An viele Clients senden Du übst Go Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Go Academy zu starten?

Keine Vorkenntnisse erforderlich. Go Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Nachrichten verteilen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Go Academy-Lektion Code schreiben und ausführen?

Ja. Jede Go Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. WebSocket-Grundlagen
  2. gorilla/websocket verwenden
  3. Nachrichten verteilen
  4. Verbindungsverwaltung
← Zurück zu Go Academy