0Pricing
Go Academy · Lekcja

Rozgłaszanie wiadomości

Wysyłaj wiadomości do wielu klientów

Rozgłaszanie wiadomości to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.

Wysyłanie do wielu klientów

Pokoje czatu i kanały danych na żywo muszą wysyłać pojedynczą wiadomość do każdego połączonego klienta. Ponieważ każdy WebSocket pozwala tylko jednemu zapisującemu, potrzebny jest wzorzec koordynacji: hub.

Wzorzec huba

Hub to centralna goroutine, która posiada zbiór klientów i kanał rozgłaszania. Klienci są rejestrowani i wyrejestrowywani, a hub rozsyła wiadomości do wszystkich. Żadna współdzielona mapa nie jest bezpośrednio modyfikowana przez wiele goroutines.

Struktury danych huba

Hub przechowuje:

  • zbiór klientów (map[*Client]bool)
  • kanał wiadomości broadcast
  • kanały register i unregister
type Hub struct {
    clients    map[*Client]bool
    broadcast  chan []byte
    register   chan *Client
    unregister chan *Client
}

Pętla działania huba

Pojedyncza goroutine Run wybiera dane z kanałów. Ponieważ tylko ta goroutine modyfikuje mapę, mutex nie jest potrzebny.

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

Kanał wysyłania dla klienta

Każdy klient ma buforowany kanał send chan []byte. Hub zapisuje do niego dane, a dedykowana goroutine zapisująca pobiera je i przesyła do gniazda. Dzięki temu przestrzegana jest zasada jednego zapisującego.

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

Goroutine zapisująca

Każdy klient uruchamia writePump, który iteruje po kanale send i zapisuje dane do gniazda. Po zamknięciu kanału wysyła ramkę zamknięcia.

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

Unikanie powolnych klientów

Jeśli jeden klient działa powoli, jego buforowany kanał send się zapełnia. Często stosuje się zasadę: gdy bufor jest pełny, należy odłączyć klienta zamiast blokować cały hub.

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

Dlaczego kanały zamiast mutexów

Maksyma języka Go brzmi: "współdziel pamięć przez komunikację". Przekazywanie wszystkich modyfikacji przez jedną goroutine za pośrednictwem kanałów pozwala uniknąć wyścigów przy dostępie do mapy klientów bez jawnego blokowania.

Rozgłaszanie wiadomości

Dowolny handler może rozgłosić wiadomość, wysyłając ją do kanału huba; hub rozsyła ją następnie do każdego zarejestrowanego klienta.

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

Wysyłanie celowane a rozgłaszanie

W przypadku pokoi lub wiadomości bezpośrednich należy przechowywać klientów według identyfikatora pokoju lub użytkownika i iterować tylko po odpowiednim podzbiorze zamiast po wszystkich klientach. Dzięki temu czat z wieloma pokojami pozostaje wydajny.

Wykonywalny przykład: rozsyłanie za pomocą kanałów

Ten samodzielny program modeluje rozsyłanie jednej wiadomości przez hub do kilku kanałów klientów, korzystając wyłącznie z biblioteki standardowej i 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()
}

Szybkie sprawdzenie

Proszę sprawdzić swoją wiedzę o rozgłaszaniu.

Podsumowanie

Nauczyli się Państwo rozsyłać wiadomości do wielu klientów:

  • goroutine huba posiada zbiór klientów i kanał rozgłaszania
  • każdy klient ma buforowany kanał wysyłania opróżniany przez goroutine zapisującą
  • przestrzegana jest zasada jednego zapisującego na połączenie
  • powolnych klientów należy odłączać, aby hub zachował responsywność

Często zadawane pytania

Czy lekcja „Rozgłaszanie wiadomości” jest bezpłatna?

Tak — pełny tekst „Rozgłaszanie wiadomości” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Rozgłaszanie wiadomości”?

Wysyłaj wiadomości do wielu klientów Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Go Academy?

Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Rozgłaszanie wiadomości”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?

Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Podstawy WebSocket
  2. Używanie gorilla/websocket
  3. Rozgłaszanie wiadomości
  4. Zarządzanie połączeniami
← Powrót do Go Academy