0Pricing
Go Academy · Lekcja

Zarządzanie połączeniami

Obsługuj rozłączenia

Zarządzanie połączeniami to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 4 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.

Połączenia nie trwają wiecznie

Klienci zamykają karty, tracą połączenie Wi-Fi lub ulegają awarii. Solidne serwery WebSocket muszą wykrywać rozłączenia, zwalniać zasoby i kończyć goroutines. W przeciwnym razie dochodzi do wycieków pamięci i gniazd.

Uzgadnianie zamknięcia

Poprawne zamknięcie wysyła ramkę zamknięcia w obu kierunkach. gorilla udostępnia tę informację jako błąd funkcji ReadMessage, wraz z kodem zamknięcia, który można sprawdzić.

if websocket.IsCloseError(err, websocket.CloseNormalClosure) {
    // graceful close
}

Podtrzymywanie połączenia za pomocą ping/pong

Aby wykryć połączenie częściowo otwarte (partner zniknął bez zamknięcia połączenia), serwer okresowo wysyła sterujące ramki ping i oczekuje odpowiedzi pong.

conn.SetPongHandler(func(string) error {
    conn.SetReadDeadline(time.Now().Add(60 * time.Second))
    return nil
})

Limity czasu odczytu

Należy ustawić limit czasu odczytu, aby nieaktywne połączenie ostatecznie zgłosiło błąd zamiast blokować wykonanie na zawsze. Limit należy odświeżać za każdym razem, gdy nadejdzie pong.

conn.SetReadDeadline(time.Now().Add(60 * time.Second))

Ticker pingów

Ticker w goroutine zapisującej wysyła ping w regularnych odstępach. Jeśli zapis się nie powiedzie, połączenie jest nieaktywne i należy zakończyć działanie.

ticker := time.NewTicker(54 * time.Second)
defer ticker.Stop()
for range ticker.C {
    if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
        return
    }
}

Sprzątanie przy kończeniu działania

Gdy pętla odczytu lub zapisu się kończy, należy wyrejestrować klienta i zamknąć połączenie. defer zapewnia wykonanie tych czynności nawet w przypadku paniki.

defer func() {
    hub.unregister <- client
    conn.Close()
}()

Dwie goroutines na połączenie

Standardowy wzorzec uruchamia dla każdego połączenia readPump i writePump. Gdy jedna z nich wykryje błąd, uruchamia sprzątanie, które zatrzymuje drugą (często przez zamknięcie kanału send).

Limity czasu zapisu również

Należy ustawić limity czasu zapisu, aby zablokowany zapis nie zawiesił goroutine na zawsze. Zapis, którego limit czasu został przekroczony, zwraca błąd, po czym należy rozłączyć połączenie.

conn.SetWriteDeadline(time.Now().Add(10 * time.Second))

Kontrolowane zamykanie serwera

Podczas zamykania serwera należy wysłać każdemu klientowi ramkę zamknięcia i krótko zaczekać. Należy połączyć to z http.Server.Shutdown oraz limitem czasu określonym przez context.

conn.WriteMessage(websocket.CloseMessage,
    websocket.FormatCloseMessage(websocket.CloseGoingAway, "bye"))

Ponowne łączenie po stronie klienta

Rozłączenia są normalne. Klienci powinni implementować logikę ponownego łączenia z wykładniczym zwiększaniem opóźnienia. Po stronie serwera wystarczy poprawnie obsługiwać każde połączenie i rozłączenie.

Wykonywalny przykład: analogia wykrywania limitu czasu

Podtrzymywanie połączenia WebSocket wymaga biblioteki; ten program korzystający z biblioteki standardowej modeluje sprawdzanie aktywności na podstawie limitu czasu za pomocą timera i kanału.

package main

import (
    "fmt"
    "time"
)

func main() {
    pong := make(chan struct{})
    go func() {
        time.Sleep(20 * time.Millisecond) // simulate a slow/absent peer
        _ = pong                          // no pong sent -> dead connection
    }()
    select {
    case <-pong:
        fmt.Println("alive")
    case <-time.After(10 * time.Millisecond):
        fmt.Println("no pong: closing dead connection")
    }
}

Szybkie sprawdzenie

Proszę sprawdzić swoją wiedzę o zarządzaniu połączeniami.

Podsumowanie

Nauczyli się Państwo zarządzać połączeniami:

  • obsługiwać uzgadnianie zamknięcia i sprawdzać kody zamknięcia
  • używać ping/pong oraz limitów czasu odczytu i zapisu do wykrywania nieaktywnych partnerów
  • uruchamiać readPump i writePump oraz sprzątać za pomocą defer
  • kontrolowanie zamykać połączenia za pomocą ramek zamknięcia; klienci ponownie łączą się ze stopniowo zwiększanym opóźnieniem

Często zadawane pytania

Czy lekcja „Zarządzanie połączeniami” jest bezpłatna?

Tak — pełny tekst „Zarządzanie połączeniami” 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 „Zarządzanie połączeniami”?

Obsługuj rozłączenia Ć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 4 z 4.

Ile czasu zajmuje lekcja „Zarządzanie połączeniami”?

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