Soketi

Soketi to oprogramowanie open-source, które działa jako serwer WebSockets, który możemy uruchomić w ramach naszego klastra Kubernetes.

Websocket – co to jest?

WebSockets to technologia komunikacyjna, która umożliwia dwukierunkową wymianę danych w czasie rzeczywistym między klientem a serwerem. Jest to kluczowy element wielu nowoczesnych aplikacji internetowych, takich jak czaty, gry online i platformy społecznościowe.

Soketi – serwer Websocket

Soketi to potężne i wszechstronne narzędzie do tworzenia aplikacji internetowych w czasie rzeczywistym. Jest łatwy w użyciu, szybki, skalowalny i kompatybilny z Pusher. Soketi to doskonały wybór dla programistów (szczególnie programistów PHP i frameworka Laravel), którzy chcą dodać funkcje w czasie rzeczywistym do swoich aplikacji.

Główne cechy Soketi:

  • Prostota: jest łatwe w instalacji i konfiguracji. Dostępne są szczegółowe instrukcje dla różnych platform i środowisk.
  • Szybkość: jest zbudowane na bazie wydajnego silnika uWebSocket.js, co zapewnia niskie opóźnienia i wysoką przepustowość.
  • Skalowalność: można skalować w poziomie, aby obsługiwać rosnącą liczbę użytkowników i połączeń.
  • Kompatybilność: jest kompatybilne z protokołem Pusher, co oznacza, że ​​może być używane jako zamiennik dla Pusher w istniejących aplikacjach.
  • Otwartość: jest oprogramowaniem open-source, co oznacza, że ​​jest bezpłatne i dostępne dla każdego.

Zastosowania Soketi:

Soketi możemy używać do różnych zastosowań, w tym:

  • Czat na żywo: używać możemy do stworzenia czatu na żywo w witrynach internetowych i aplikacjach.
  • Powiadomienia w czasie rzeczywistym: używać możemy do wysyłania powiadomień do użytkowników w czasie rzeczywistym, na przykład o nowych wiadomościach lub aktualizacjach.
  • Gry online: możemy używać do tworzenia gier online w czasie rzeczywistym.
  • Platformy społecznościowe: możemy używać do tworzenia funkcji społecznościowych w czasie rzeczywistym, takich jak strumieniowanie na żywo i uaktualnienia statusu.

Soketi na Kubernetes

Wdrożenie Soketi w ramach klastra Kubernetes jest wyjątkowo prosta i realizujemy ją przy pomocy kilku komponentów zależnych. Jako że pokażę Wam wdrożenie, które pozwala na skalowanie horyzontalne, będę wykorzystywać konkretną konfigurację.

Soketi wspiera kilka sposobów wdrożeń. Zacznijmy od konfiguracji.

Każdy serwer może posiadać X aplikacji, które możemy zdefiniować „twardo” poprzez plik json, albo dynamicznie z wykorzystaniem MySQL, PostgreSQL lub DynamoDB. Ja skorzystam z MySQL, a dodatkowo by móc skalować horyzontalnie (czyli zwiększać ilość instancji. Jak skalujemy serwer zwiększając „moc” to nazywamy to skalowaniem wertykalnym) potrzebujemy czegoś do trzymania kolejki, w naszym wypadku będzie to stary, dobry Redis w wersji Single-node.

Wdrożenie wykonamy przy pomocy Helm. Helm to narzędzie open-source, które ułatwia instalowanie i zarządzanie aplikacjami na klastrach Kubernetes. Działa jak menedżer pakietów, udostępniając repozytoria z gotowymi do użycia aplikacjami zwanymi Chartami. Dzięki temu nie musimy samodzielnie „klepać” plików YAML 🙂

W takim razie, skoro już posiadamy bazę danych MySQL, serwer Redis i zainstalowany Helm oraz klaster Kubernetes wraz z serwerem Ingressa (np.: nginx-ingress) to możemy przystąpić do działania.

Na początek przygotujmy sobie plik values.yml:

nameOverride: "nazwa"

ingress:
  enabled: true
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: soketi.adres.serwera
      paths:
        - /
  tls:
    - secretName: soketi.tls
      hosts:
        - soketi.adres.serwera
  class: nginx

# autoscaling:
#   enabled: true
#   minReplicas: 1
#   maxReplicas: 3
#   targetCPUUtilizationPercentage: 80

app:
  extraEnv:
    - name: SOKETI_ADAPTER_DRIVER
      value: "redis"
    - name: SOKETI_ADAPTER_REDIS_PREFIX
      value: "soketi:"
    - name: SOKETI_DEBUG
      value: "1"
    - name: SOKETI_DB_REDIS_HOST
      value: "redis.adres.serwera"
    - name: SOKETI_DB_REDIS_DB
      value: "1"
    - name: SOKETI_DB_REDIS_USERNAME
      value: "soketi"
    - name: SOKETI_DB_REDIS_PASSWORD
      value: "HASLOTAKIETRUDNE"
    - name: SOKETI_DB_REDIS_KEY_PREFIX
      value: "soketi:"
    - name: SOKETI_APP_MANAGER_DRIVER
      value: "mysql"
    - name: SOKETI_APP_MANAGER_MYSQL_USE_V2
      value: "true"
    - name: SOKETI_DB_MYSQL_HOST
      value: "mysql.adres.serwera"
    - name: SOKETI_DB_MYSQL_PORT
      value: "3306"
    - name: SOKETI_DB_MYSQL_DATABASE
      value: "soketi"
    - name: SOKETI_DB_MYSQL_USERNAME
      value: "soketi"
    - name: SOKETI_DB_MYSQL_PASSWORD
      value: "BARDZIEJ_TRUDNE_HASLO_HEHE"

Jak widzimy w powyższym, idąc po kolei:

  • nameOverride – nadpiszemy sobie nazwę naszego charta, by móc sobie w razie czego łatwiej znaleźć
  • ingress – w tej sekcji konfigurujemy ingressa. Podajemy nazwę hosta, nazwę sekretu z certyfikatem i/lub tak jak w moim przypadku – dodatkowo annotations z konfiguracją mojego issuera z Lets Encrypt (cert-manager.io).
  • autoscaling mam zakomentowany, ale tam definiujemy jak bardzo aplikacja może się skalować na bazie wykorzystania procesora.
  • app – w tej sekcji definiujemy wszystkie zmienne środowiskowe dla aplikacji, czyli dane dostępowe do Redisa i MySQL. Bez tego nasza aplikacja nic nie zrobi. Więcej zmiennych znajdziesz w dokumentacji, a linki do dokumentacji będą na końcu artykułu.

Kolejnym etapem będzie stworzenie tabeli w bazie:

CREATE TABLE IF NOT EXISTS `apps` (
    `id` varchar(255) NOT NULL,
    `key` varchar(255) NOT NULL,
    `secret` varchar(255) NOT NULL,
    `max_connections` integer(10) NOT NULL,
    `enable_client_messages` tinyint(1) NOT NULL,
    `enabled` tinyint(1) NOT NULL,
    `max_backend_events_per_sec` integer(10) NOT NULL,
    `max_client_events_per_sec` integer(10) NOT NULL,
    `max_read_req_per_sec` integer(10) NOT NULL,
    `webhooks` json,
    `max_presence_members_per_channel` tinyint(1) NULL,
    `max_presence_member_size_in_kb` tinyint(1) NULL,
    `max_channel_name_length` tinyint(1) NULL,
    `max_event_channels_at_once` tinyint(1) NULL,
    `max_event_name_length` tinyint(1) NULL,
    `max_event_payload_in_kb` tinyint(1) NULL,
    `max_event_batch_size` tinyint(1) NULL,
    `enable_user_authentication` tinyint(1) NOT NULL,
    PRIMARY KEY (`id`)
);

A na samym końcu — instalacja! Pierw dodamy sobie repozytorium do naszego menedżera pakietów, a potem zainstalujemy sam serwer:

helm repo add soketi https://helm.soketi.app
helm repo update

helm upgrade soketi \
    --install \
    --version=2.0.0 \
    --namespace=soketi \
    --create-namespace \
    --values=values.yaml \
    soketi/soketi

Podsumowanie

Instalacja tego serwera websocket to bardzo proste zadanie, nie wymaga ono dużego nakładu pracy.

Dokumentacje:

Dołącz do newslettera, by być na bieżąco!

Jeśli chcesz być na bieżąco z blogiem, otrzymywać świetne porady dot. programowania i administracji serwerami, opinie w temacie gier - dołącz do newslettera!

Raz na jakiś czas wyślę Ci informację nt. bloga, a także będę wysyłać ekskluzywne materiały techniczne!

Nie czekaj i dołącz!

Dołączając do newslettera, akceptujesz naszą politykę prywatności!