0Pricing
Frontend Academy · Lekcja

WebSocket API: open, message, close, error

Utworzy Pan/Pani połączenie WebSocket, będzie wysyłać i odbierać wiadomości w module obsługi zdarzenia message oraz obsłuży błędy połączenia i jego prawidłowe zamykanie.

WebSocket API: open, message, close, error to bezpłatna lekcja Frontend Academy na CoddyKit. To lekcja 1 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 Frontend Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Frontend Academy zawiera 4 lekcji w sumie.

Dlaczego WebSocket?

HTTP działa w modelu żądanie–odpowiedź. W aplikacjach czasu rzeczywistego, takich jak czaty, gry wieloosobowe i aktualizacje na żywo, potrzebna jest trwała dwukierunkowa komunikacja. WebSocket zapewnia pojedyncze połączenie TCP, które pozostaje otwarte i pozwala obu stronom wysyłać wiadomości w dowolnym momencie.

Tworzenie WebSocket

Należy utworzyć WebSocket za pomocą adresu URL zaczynającego się od ws:// lub wss://. Przeglądarka obsługuje uzgadnianie przejścia na ten protokół.

const ws = new WebSocket('wss://api.example.com/realtime');

// Always use wss:// (secure) in production

Cztery zdarzenia

WebSocket ma cztery typy zdarzeń: open (połączenie nawiązane), message (odebrano dane), close (połączenie zakończone), error (problem).

ws.addEventListener('open', () => {
  console.log('Connected');
  ws.send(JSON.stringify({ type: 'subscribe', channel: 'updates' }));
});

ws.addEventListener('message', (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
});

ws.addEventListener('close', (event) => {
  console.log('Closed:', event.code, event.reason);
});

ws.addEventListener('error', (event) => {
  console.error('Error:', event);
});

Wysyłanie wiadomości

Należy użyć ws.send(). Metoda przyjmuje ciągi znaków, ArrayBuffers, Blobs lub ArrayBufferView. W przypadku danych o ustrukturyzowanej postaci najpierw należy użyć JSON.stringify.

ws.send('hello');
ws.send(JSON.stringify({ type: 'chat', text: 'Hi' }));

// Binary:
const buffer = new ArrayBuffer(8);
ws.send(buffer);

Odbieranie wiadomości

Należy sprawdzić event.data — jego typ odpowiada typowi danych wysłanych przez serwer. W przypadku danych reprezentujących obiekt należy użyć JSON.parse.

ws.addEventListener('message', (event) => {
  // typeof event.data: string | ArrayBuffer | Blob
  if (typeof event.data === 'string') {
    const msg = JSON.parse(event.data);
    handleMessage(msg);
  }
});

Stan połączenia (readyState)

Należy sprawdzić ws.readyState: CONNECTING=0, OPEN=1, CLOSING=2, CLOSED=3. Nie należy wysyłać danych przed przejściem do stanu OPEN.

if (ws.readyState === WebSocket.OPEN) {
  ws.send(message);
} else {
  console.warn('Not connected yet');
}

Prawidłowe zamykanie połączenia

Należy wywołać ws.close(code, reason). Standardowe kody zamknięcia to: 1000 (normalne), 1001 (opuszczenie połączenia), 1008 (naruszenie zasad), 1011 (błąd serwera).

ws.close(1000, 'User logged out');

Strategia ponownego połączenia

WebSockety rozłączają się między innymi po zmianie sieci lub ponownym uruchomieniu serwera. Należy zaimplementować ponowne połączenie z wykładniczym zwiększaniem opóźnienia.

let reconnectDelay = 1000;

function connect() {
  const ws = new WebSocket('wss://api/realtime');
  ws.addEventListener('open', () => { reconnectDelay = 1000; });
  ws.addEventListener('close', () => {
    setTimeout(connect, reconnectDelay);
    reconnectDelay = Math.min(reconnectDelay * 2, 30000);
  });
  return ws;
}

Mechanizm heartbeat / podtrzymywanie połączenia

Nieaktywne połączenia WebSocket są zamykane przez serwery proxy i moduły równoważenia obciążenia po około 60 sekundach. Aby utrzymać połączenie, należy wysyłać ping co 25–30 sekund.

let pingInterval;
ws.addEventListener('open', () => {
  pingInterval = setInterval(() => {
    if (ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({ type: 'ping' }));
    }
  }, 25000);
});
ws.addEventListener('close', () => clearInterval(pingInterval));

Uwierzytelnianie

WebSockety nie obsługują niestandardowych nagłówków. Dostępne są następujące opcje: 1) uwierzytelnianie za pomocą tokenu w ciągu zapytania (?token=jwt) adresu URL WS; 2) wysłanie wiadomości uwierzytelniającej po zdarzeniu open; 3) użycie pliku cookie (działa automatycznie w przypadku tego samego źródła).

// Query string:
const ws = new WebSocket(`wss://api/realtime?token=${jwt}`);

// Auth message:
ws.addEventListener('open', () => {
  ws.send(JSON.stringify({ type: 'auth', token: jwt }));
});

Hook React dla WebSocket

Cykl życia WS należy zamknąć w niestandardowym hooku, aby uniknąć wycieków połączeń.

function useWebSocket(url) {
  const [messages, setMessages] = useState([]);
  const wsRef = useRef(null);

  useEffect(() => {
    const ws = new WebSocket(url);
    wsRef.current = ws;
    ws.addEventListener('message', (e) => {
      setMessages(m => [...m, JSON.parse(e.data)]);
    });
    return () => ws.close();
  }, [url]);

  return { messages, send: (msg) => wsRef.current?.send(JSON.stringify(msg)) };
}

WebSocket a HTTP/2 i SSE

WebSocket: pełny dupleks, obie strony mogą wysyłać dane. Server push w HTTP/2: przestarzały. Server-Sent Events: tylko komunikacja z serwera do klienta, prostsza i z automatycznym ponownym łączeniem. Należy wybrać WS, gdy klient także musi wysyłać dane, na przykład w czacie; SSE sprawdzi się przy powiadomieniach jednokierunkowych.

Szybkie sprawdzenie

Jaki jest standardowy kod zamknięcia WebSocket dla normalnego, zamierzonego zamknięcia, na przykład po wylogowaniu użytkownika?

Podsumowanie: WebSocket API

new WebSocket('wss://...') otwiera połączenie. Cztery zdarzenia to: open, message, close i error. send() przyjmuje string, ArrayBuffer lub Blob; w przypadku obiektów należy użyć JSON.stringify. Przed wysłaniem należy sprawdzić readyState. close(1000) służy do prawidłowego zamknięcia połączenia. Ponowne połączenie należy realizować z wykładniczym zwiększaniem opóźnienia. Heartbeat co 25 sekund podtrzymuje połączenie. Uwierzytelnianie może odbywać się za pomocą ciągu zapytania lub wiadomości uwierzytelniającej. W React cykl życia należy opakować w hook.

Często zadawane pytania

Czy lekcja „WebSocket API: open, message, close, error” jest bezpłatna?

Tak — pełny tekst „WebSocket API: open, message, close, error” 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 Frontend Academy, przejdź na CoddyKit PRO. Kurs Frontend Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „WebSocket API: open, message, close, error”?

Utworzy Pan/Pani połączenie WebSocket, będzie wysyłać i odbierać wiadomości w module obsługi zdarzenia message oraz obsłuży błędy połączenia i jego prawidłowe zamykanie. Ćwiczysz Frontend 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ąć Frontend Academy?

Nie wymagamy żadnego doświadczenia. Frontend 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 1 z 4.

Ile czasu zajmuje lekcja „WebSocket API: open, message, close, error”?

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 Frontend Academy?

Tak. Każda lekcja Frontend 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. WebSocket API: open, message, close, error
  2. Integracja klienta Socket.io
  3. Server-Sent Events do strumieniowania jednokierunkowego
  4. Wzorce interfejsów czasu rzeczywistego
← Powrót do Frontend Academy