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
registeriunregister
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
- Podstawy WebSocket
- Używanie gorilla/websocket
- Rozgłaszanie wiadomości
- Zarządzanie połączeniami