Programowanie Java WebSocket z Androidem i Spring Boot
Published: 2024-01-17 02:18:40

Protokół [WebSocket](https://www.pubnub.com/blog/websockets-vs-rest-api-understanding-the-difference/) zapewnia zawsze aktywne połączenie między klientem a serwerem w celu dwukierunkowej komunikacji. Jest to świetne rozwiązanie dla aplikacji, które wymagają połączenia w czasie rzeczywistym, takich jak [gry wieloosobowe](https://www.pubnub.com/industry/gaming/), [aplikacje Internetu rzeczy](https://www.pubnub.com/industry/iot-and-connected-devices/) i [aplikacje do czatowania](https://www.pubnub.com/use-case/in-app-chat/). Przypadkiem użycia w tym samouczku jest aplikacja czatu, klasyczny przykład komunikacji w czasie rzeczywistym. W tym samouczku skonfigurujemy prostego klienta Android, który będzie łączył się z serwerem WebSocket przy użyciu [Spring Boot](https://spring.io/projects/spring-boot).

![](/cdn/3prze68gbwl1/archivedasset-17su7vkk2ohxnb3/97e1b1e1ab1a6f2f7de233157b9e0c31/WebSockets-Diagram.png)

Klient Java WebSocket
---------------------

Dla klienta Androida stworzymy prostą aplikację demonstracyjną zawierającą cztery przyciski z obrazkami uroczych zwierzątek. Przed zagłębieniem się w implementację Java warto zauważyć, że Kotlin stał się popularnym wyborem dla rozwoju Androida. Aby rozpocząć, zainicjuj nowy projekt w [Android Studio](https://developer.android.com/studio), z aktywnością podstawową o nazwie **JavaWebSocketClient**. Zamierzamy użyć lekkiej biblioteki klienta WebSocket dla aplikacji, którą można znaleźć w tym [repozytorium](https://github.com/gusavila92/java-android-websocket-client) GitHub. Aby użyć tej biblioteki, musimy dodać ją do pliku **build.gradle** w katalogu aplikacji. Dodaj następujące elementy do zależności i zsynchronizuj projekt:

```js
dependencies { 
    // Add this
    implementation 'tech.gusavila92:java-android-websocket-client:<latest-version>'    
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ...
}
```

Upewnij się, że w pliku manifestu znajduje się uprawnienie dostępu do Internetu:

```js
<uses-permission android:name="android.permission.INTERNET" />
```

### Połącz klienta z serwerem

Przejdź do **MainActivity.java**, zaimportuj następujące pakiety i skonfiguruj **onCreate()**:

```js
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import java.net.URI;
import java.net.URISyntaxException;
import tech.gusavila92.websocketclient.WebSocketClient;

public class MainActivity extends AppCompatActivity {
  private WebSocketClient webSocketClient;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.animal_sounds);
    createWebSocketClient();
  }
}
```

Następnie utwórz nową metodę **createWebSocketClient()**:

```js
private void createWebSocketClient() {
    URI uri;
    try {
      // Connect to local host
      uri = new URI("ws://10.0.2.2:8080/websocket");
    }
    catch (URISyntaxException e) {
      e.printStackTrace();
      return;
    }

    webSocketClient = new WebSocketClient(uri) {
      @Override
      public void onOpen() {
        Log.i("WebSocket", "Session is starting");
        webSocketClient.send("Hello World!");
      }

      @Override
      public void onTextReceived(String s) {
        Log.i("WebSocket", "Message received");
        final String message = s;
        runOnUiThread(new Runnable() {
          @Override
          public void run() {
            try{
              TextView textView = findViewById(R.id.animalSound);
              textView.setText(message);
            } catch (Exception e){
                e.printStackTrace();
            }
          }
        });
      }

      @Override
      public void onBinaryReceived(byte[] data) {
      }

      @Override
      public void onPingReceived(byte[] data) {
      }

      @Override
      public void onPongReceived(byte[] data) {
      }

      @Override
      public void onException(Exception e) {
        Log.e("WebSocket", e.getMessage());
      }

      @Override
      public void onCloseReceived() {
        Log.i("WebSocket", "Closed ");
      }
    };

    webSocketClient.setConnectTimeout(10000);
    webSocketClient.setReadTimeout(60000);
    webSocketClient.enableAutomaticReconnection(5000);
    webSocketClient.connect();
  }
```

Może to wyglądać na dużo, ale tak naprawdę robimy cztery kluczowe rzeczy w tej metodzie:

1.  Rozpoczęcie nowego połączenia WebSocket do localhost "ws://10.0.2.2:8080/websocket".
    
2.  Wysyłanie wiadomości do serwera po otwarciu połączenia.
    
3.  Wyświetlanie wiadomości wysłanych z serwera w aplikacji.
    
4.  Ustawianie limitów czasu i automatycznego ponownego połączenia.
    

Teraz, gdy połączyliśmy klienta z serwerem, skonfigurujmy metodę wysyłania wiadomości do serwera.

### Wysyłanie wiadomości do serwera

W **MainActivity.java** dodaj następujące elementy do **sendMessage()**:

```js
public void sendMessage(View view) {
   Log.i("WebSocket", "Button was clicked");

   // Send button id string to WebSocket Server
   switch(view.getId()){
     case(R.id.dogButton):
       webSocketClient.send("1");
       break;

     case(R.id.catButton):
       webSocketClient.send("2");
       break;

     case(R.id.pigButton):
       webSocketClient.send("3");
       break;

     case(R.id.foxButton):
       webSocketClient.send("4");
       break;
   }
 }
```

Po naciśnięciu przycisku _identyfikator_ przycisku jest wysyłany do serwera. Ta metoda jest wywoływana z pliku **animal\_sounds.xml**, który można pobrać z mojego [Java WebSocket Programming Repo](https://github.com/ocastroa/java-websocket-demo/blob/master/JavaWebSocketClient/app/src/main/res/layout/animal_sounds.xml). Upewnij się, że zmodyfikowałeś plik [**strings.**](https://github.com/ocastroa/java-websocket-demo/blob/master/JavaWebSocketClient/app/src/main/res/values/strings.xml) xml w katalogu **values**, aby uniknąć błędów w pliku XML.

Ostatnią rzeczą do zrobienia po stronie klienta jest dodanie obrazów zwierząt do katalogu [**drawable**](https://github.com/ocastroa/java-websocket-demo/tree/master/JavaWebSocketClient/app/src/main/res/drawable). _Obrazy są tworzone przez_ [_Freepik_](https://www.flaticon.com/authors/freepik) _z_ _www.flaticon.com._

Uruchom aplikację na Androida w emulatorze:

![](/cdn/3prze68gbwl1/asset-17suaysk1qa1k1d/c3da7192b47d3ca4e89d9012ad20fa62/clicking_buttons_client.gif?w=700&h=550)

W tej chwili nic się nie dzieje, ponieważ serwer nie jest skonfigurowany. Zróbmy to teraz!

Spring Boot WebSocket Server
----------------------------

Dla naszego serwera użyjemy Spring Boot, który ułatwia tworzenie aplikacji [Spring](https://spring.io/projects/spring-framework) klasy produkcyjnej przy minimalnych konfiguracjach. Aby szybko uruchomić nasz projekt, użyjemy [Spring Initializr](https://start.spring.io/). Wygenerujemy projekt [Gradle](https://gradle.org/), ale jeśli wolisz, możesz również wygenerować projekt [Maven](https://maven.apache.org/). Skonfiguruj Initializr jak na poniższym zrzucie ekranu i upewnij się, że dodałeś WebSocket jako zależność:

![](/cdn/3prze68gbwl1/asset-17suaysk1qa1k1e/3a66f9b5a0a6dcdee6f40f92a45d59fc/spring_initializr-1.png)

Wygeneruj projekt, aby pobrać plik zip. Po rozpakowaniu pliku przejdź do katalogu **src** i klikaj podkatalogi, aż dojdziesz do pliku **JavaWebSocketServerApplication.java**.

```js
package com.example.javawebsocketserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JavaWebSocketServerApplication {
  public static void main(String[] args) {
    SpringApplication.run(JavawebsocketserverApplication.class, args);
  }
}
```

Dodaj dwa pliki do katalogu **WebSocketHandler** .java i **WebSocketConfiguration.**java.

### Obsługa komunikatów WebSocket

Musimy obsłużyć przychodzące wiadomości, które docierają do serwera. Aby to zrobić, w **WebSocketHandler** .java odziedzicz klasę, aby zaimplementować metodę **handleTextMessage()**. Dodaj następujący kod do pliku:

```js
package com.server.javawebsocketserver;

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import java.io.IOException;

public class WebSocketHandler extends AbstractWebSocketHandler {
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        String msg = String.valueOf(message.getPayload());
        // Send back a unique message depending on the id received from the client
        switch(msg){
            case("1"):
                Log.i("WebSocket", "Dog button was pressed");
                session.sendMessage(new TextMessage("Woooof"));
                break;

            case("2"):
                Log.i("WebSocket", "Cat button was pressed");
                session.sendMessage(new TextMessage("Meooow"));
                break;

            case("3"):
                Log.i("WebSocket", "Pig button was pressed");
                session.sendMessage(new TextMessage("Bork Bork"));
                break;

            case("4"):
                Log.i("WebSocket", "Fox button was pressed");
                session.sendMessage(new TextMessage("Fraka-kaka-kaka"));
                break;

            default:
                Log.i("WebSocket", "Connected to Client");
        }
    }
}
```

Wewnątrz metody po prostu pobieramy wartość ciągu ładunku wiadomości i wykonujemy wyrażenie **przełączające**, aby sprawdzić wartość wiadomości z wartością każdego przypadku. Unikalna wiadomość z dźwiękiem zwierzęcia jest wysyłana do klienta.

### Konfiguracja obsługi żądań WebSocket

W **WebSocketConfiguration.java** zaimplementuj interfejs [**WebSocketConfigurer**](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/socket/config/annotation/WebSocketConfigurer.html) i dodaj następujący kod do pliku:

```js
package com.server.javawebsocketserver;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new WebSocketHandler(), "/websocket");
    }
}
```

Ustawiamy metodę **registerWebSocketHandlers**, aby skonfigurować [WebSocketHandler](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/socket/config/annotation/WebSocketConfigurer.html#addHandler-org.springframework.web.socket.WebSocketHandler-java.lang.String...-) do ścieżki "**/websocket**". To wszystko po stronie serwera. Teraz, gdy mamy już wszystko skonfigurowane, uruchommy serwer WebSocket i uruchommy aplikację!

Wysyłanie danych między serwerem a klientem
-------------------------------------------

W terminalu przejdź do katalogu głównego projektu Spring Boot i uruchom następujące polecenie, aby uruchomić serwer:

```js
gradle bootRun
```

Następnie uruchom klienta Android w Android Studio, a po załadowaniu aplikacji kliknij dowolny z czterech przycisków.

![](/cdn/3prze68gbwl1/asset-17suaysk1qa1k1f/6153c8947488b515b3166179789f8562/client_server_screenshot.png)

Pobaw się aplikacją na Androida i zobacz, jak wiadomości są wysyłane od klienta do serwera za pomocą WebSockets!

Aktualizacja klienta Android do Pub/Sub
---------------------------------------

Wysyłanie danych klient-serwer lub serwer-klient nie jest trudne i można to zrobić dość szybko. Ale co jeśli chcesz wysłać dane od klienta do klienta? Nie można bezpośrednio połączyć klientów bez zaimplementowania logiki routingu i brokera wiadomości (poprzez `enableSimpleBroker` i zarejestrowanie go w typie `MessageBrokerRegistry` ) na serwerze.

Istnieje kilka narzędzi, których możemy użyć, aby uczynić to zadanie mniej czasochłonnym. Jednym z takich narzędzi jest [Socket.IO](http://socket.io/), które ustanawia dwukierunkowe połączenie między klientami w czasie rzeczywistym. Jest to świetne narzędzie open-source, ale nadal musimy skonfigurować serwer i połączyć klienta z serwerem. Innym takim narzędziem jest użycie podprotokołów, takich jak [STOMP](https://en.wikipedia.org/wiki/Streaming_Text_Oriented_Messaging_Protocol) w Spring Boot, aby osadzić wiadomości STOMP. Ten podprotokół działa na szczycie WebSocket i umożliwia obsługę wiadomości WebSocket. Jednak trzeba również samodzielnie skonfigurować punkty końcowe za pomocą typu `StompEndpointRegistry`, a następnie dodać punkty końcowe za pomocą metody `addEndPoint`. Czy istnieje łatwiejszy sposób na bezpieczne i niezawodne przesyłanie danych między klientami bez ręcznego konfigurowania serwera? Dzięki PubNub jest to możliwe.

![](/cdn/3prze68gbwl1/asset-17suaysk1qa1k1g/7e74251d4425718e24dd4c587e849ca5/pubsub-1.gif?w=700&h=550)

PubNub zapewnia infrastrukturę czasu rzeczywistego do zasilania dowolnego urządzenia obsługującego protokół [TCP](https://www.pubnub.com/guides/tcp-ip/). Możemy przesyłać strumieniowo dane od klienta do klienta, od klienta do serwera lub od serwera do klienta za pomocą [globalnej sieci strumieni](https://www.pubnub.com/products/pubnub-platform/) danych PubNub w czasie poniżej 100 ms! Dzięki PubNub, zawsze aktywne połączenie jest nawiązywane między urządzeniami podłączonymi do kanału, podobnie jak w przypadku WebSockets. Najlepsze jest to, że nie musisz martwić się o konfigurację serwera zaplecza i utrzymanie serwera, ponieważ PubNub jest [bezserwerowy](https://www.pubnub.com/blog/everything-you-wanted-to-know-about-serverless-but-were-afraid-to-ask/) i nieskończenie skalowalny.

Aby zobaczyć, jak PubNub upraszcza proces wysyłania danych od klienta do klienta, zmodyfikujemy aplikację na Androida, którą zbudowaliśmy wcześniej. Najpierw jednak [zarejestruj](https://admin.pubnub.com/#/signup) darmowe konto PubNub, aby otrzymać **bezpłatne klucze Pub/Sub API**.

### Modyfikacja klienta Android

Aby odróżnić zaktualizowaną aplikację od starej, utwórz nowy projekt na Androida o nazwie **PubNubJavaClient**. Aby korzystać z [Android SDK Pub](https://www.pubnub.com/docs/sdks/java/android/)Nub, zaktualizuj json, dodając następujące elementy do pliku build.gradle w katalogu aplikacji i zsynchronizuj projekt:

```js
dependencies {
    implementation group: 'com.pubnub', name: 'pubnub-gson', version: '6.4.5' // Add this
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ...
}
```

Dołącz następujące uprawnienia do pliku manifestu:

```js
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
```

Wszystko inne, z wyjątkiem **MainActivity.java**, jest takie samo. Z poprzedniej aplikacji dodaj następujące pliki do zaktualizowanej aplikacji: [**animal\_sounds.xml**](https://github.com/ocastroa/java-websocket-demo/blob/master/JavaWebSocketClient/app/src/main/res/layout/animal_sounds.xml), [**strings.xml**](https://github.com/ocastroa/java-websocket-demo/blob/master/JavaWebSocketClient/app/src/main/res/values/strings.xml) i obrazy z katalogu [**drawable**](https://github.com/ocastroa/java-websocket-demo/tree/master/JavaWebSocketClient/app/src/main/res/drawable). Po zakończeniu tych czynności przejdź do **MainActivity.** java, aby dodać nowy kod. Zaimportuj następujące pakiety i skonfiguruj funkcję **onCreate()**:

```js
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.pubnub.api.PNConfiguration;
import com.pubnub.api.PubNub;
import com.pubnub.api.callbacks.PNCallback;
import com.pubnub.api.callbacks.SubscribeCallback;
import com.pubnub.api.models.consumer.PNPublishResult;
import com.pubnub.api.models.consumer.PNStatus;
import com.pubnub.api.models.consumer.pubsub.PNMessageResult;
import com.pubnub.api.models.consumer.pubsub.PNPresenceEventResult;
import java.util.Arrays;

public class MainActivity extends AppCompatActivity {
  PubNub pubnub;
  TextView textView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.animal_sounds);

    initPubNub(); // Initialize PubNub
  }
```

Wykonaj wywołanie **initPubNub** (), aby zainicjować PubNub:

```js
public void initPubNub(){
  PNConfiguration pnConfiguration = new PNConfiguration();
  pnConfiguration.setPublishKey("ENTER_YOUR_PUB_KEY"); // REPLACE with your pub key
  pnConfiguration.setSubscribeKey("ENTER_YOUR_SUB_KEY"); // REPLACE with your sub key
  pnConfiguration.setSecure(true);
  pubnub = new PubNub(pnConfiguration);

  // Listen to messages that arrive on the channel
  pubnub.addListener(new SubscribeCallback() {
    @Override
    public void status(PubNub pub, PNStatus status) {
    }

    @Override
    public void message(PubNub pub, final PNMessageResult message) {
      // Replace double quotes with a blank space
      final String msg = message.getMessage().toString().replace("\"", ""); 
      textView = findViewById(R.id.animalSound);

      runOnUiThread(new Runnable() {
        @Override
        public void run() {
          try{
            // Display the message on the app
            textView.setText(msg);
          } catch (Exception e){
              System.out.println("Error");
              e.printStackTrace();
          }
        }
      });
    }

    @Override
    public void presence(PubNub pub, PNPresenceEventResult presence) {
    }
  });

  // Subscribe to the global channel
  pubnub.subscribe()
    .channels(Arrays.asList("global_channel"))
    .execute();
}
```

W tej metodzie wykonujemy trzy kluczowe czynności:

1.  Inicjalizujemy API klienta PubNub. Upewnij się, że zastąpiłeś "ENTER\_YOUR\_PUB\_KEY" i "ENTER\_YOUR\_SUB\_KEY" swoimi kluczami Pub/Sub.
    
2.  Skonfiguruj słuchacza, aby otrzymywać powiadomienia o wiadomościach przychodzących na kanał. Podobnie jak wcześniej, wyświetl wiadomość w aplikacji, aby klient mógł ją zobaczyć.
    
3.  Subskrybuj kanał globalny, na którym będą publikowane wiadomości.
    

Gdy użytkownik naciśnie przycisk, wywoływana jest metoda **sendMessage(** ):

```js
// This method is called when a button is pressed
public void sendMessage(View view) {
  // Get button ID
  switch(view.getId()){
    case(R.id.dogButton):
      publishMessage("Woooof");
      break;

    case(R.id.catButton):
      publishMessage("Meooow");
      break;

    case(R.id.pigButton):
      publishMessage("Bork Bork");
      break;

    case(R.id.foxButton):
      publishMessage("Fraka-kaka-kaka");
      break;
  }
}
```

Ta metoda jest podobna do tego, co zrobiliśmy wcześniej, z wyjątkiem tego, że teraz publikujemy rzeczywistą wiadomość, dźwięk zwierzęcia, na kanale globalnym, a nie na serwerze. Używamy **publishMessage** () jako funkcji pomocniczej do opublikowania wiadomości.

```js
public void publishMessage(String animal_sound){
  // Publish message to the global chanel
  pubnub.publish()
    .message(animal_sound)
    .channel("global_channel")
    .async(new PNCallback<PNPublishResult>() {
      @Override
      public void onResponse(PNPublishResult result, PNStatus status) {
        // status.isError() to see if error happened and print status code if error
        if(status.isError()) {
          System.out.println("pub status code: " + status.getStatusCode());
        }
      }
    });
}
```

To wszystko, czego potrzebujemy, aby uruchomić aplikację!

Wysyłanie danych między klientami
---------------------------------

Uruchom aplikację na Androida w dwóch emulatorach, aby zobaczyć, jak wiadomości pojawiają się w czasie rzeczywistym.

![](/cdn/3prze68gbwl1/asset-17suaysk1qa1k1h/b19bdcfbe68755a7d419c30f9281286c/client_to_client.gif?w=700&h=550)

Uwaga: Aby zapewnić płynną komunikację między klientami, upewnij się, że oba emulatory Androida mają te same klucze PubNub i są subskrybowane na tym samym kanale. Ma to kluczowe znaczenie dla ustanowienia udanego połączenia WebSocket do komunikacji w czasie rzeczywistym.

Teraz, gdy nauczyłeś się wysyłać dane za pomocą WebSockets w Javie, nie zapomnij zapoznać się z naszymi innymi zasobami.

Na koniec zapoznaj się z naszą dokumentacją, aby dowiedzieć się o dodatkowych funkcjach oferowanych przez PubNub, takich jak [Message Actions](https://www.pubnub.com/docs/chat/sdks/messages/sending-messages), [Objects](https://www.pubnub.com/docs/general/setup/users-and-devices) i [Signal](https://www.pubnub.com/docs/general/basics/send-messages), aby zapewnić swojej aplikacji solidną przewagę. Sprawdź nasze zaktualizowane zrzuty ekranu i linki do zasobów, aby uzyskać bardziej kompleksowe zrozumienie.

Dzięki PubNub możesz także tworzyć rozwiązania dostosowane do [geolokalizacji](https://www.pubnub.com/solutions/geolocation/), [szyny komunikatów brzegowych](https://www.pubnub.com/solutions/edge-message-bus/), [oprogramowania dla przedsiębiorstw](https://www.pubnub.com/solutions/enterprise-software/), [gier](https://www.pubnub.com/solutions/gaming/), [cyfrowego zdrowia](https://www.pubnub.com/solutions/digital-health/) i [handlu elektronicznego](https://www.pubnub.com/solutions/ecommerce/).

Aby rozpocząć, warto zapoznać się z naszym [ogólnym przewodnikiem konfiguracji](https://www.pubnub.com/docs/general/basics/set-up-your-account), który przeprowadzi Cię przez proces zakładania konta. Jeśli chcesz dowiedzieć się, jak wysyłać i odbierać wiadomości, mamy również przewodniki na ten temat. Więcej informacji można znaleźć w naszych przewodnikach [wysyłania](https://www.pubnub.com/docs/general/basics/send-messages) i [odbierania](https://www.pubnub.com/docs/general/basics/receive-messages) wiadomości.

Bardziej zaawansowane funkcje, takie jak wysyłanie wiadomości, [potwierdzenia](https://www.pubnub.com/docs/chat/sdks/messages/message-receipts) wiadomości i liczba nieprzeczytanych wiadomości w scenariuszu czatu, można znaleźć w tych dokumentach: [wysyłanie wiadomości](https://www.pubnub.com/docs/chat/sdks/messages/sending-messages), [potwierdzenia wiadomości](https://www.pubnub.com/docs/chat/sdks/messages/message-receipts) i [liczba nieprzeczytanych](https://www.pubnub.com/docs/chat/sdks/messages/unread-counts) wiadomości.

Jeśli pracujesz na platformie Android i chcesz zaimplementować powiadomienia push, mamy wszystko pod kontrolą. Odwiedź nasz [przewodnik Android push](https://www.pubnub.com/docs/general/push/android) i [przewodnik send push](https://www.pubnub.com/docs/general/push/send), aby uzyskać szczegółowe instrukcje dotyczące konfigurowania powiadomień push za pomocą Firebase i PubNub.

Masz sugestie lub pytania dotyczące treści tego wpisu? Skontaktuj się z nami pod adresem [devrel@pubnub.com](mailto:devrel@pubnub.com).

Jak PubNub może ci pomóc?
=========================

Ten artykuł został pierwotnie opublikowany na PubNub [.com](https://www.pubnub.com/blog/java-websocket-programming-with-android-and-spring-boot/)

Nasza platforma pomaga programistom tworzyć, dostarczać i zarządzać interaktywnością w czasie rzeczywistym dla aplikacji internetowych, aplikacji mobilnych i urządzeń IoT.

Podstawą naszej platformy jest największa w branży i najbardziej skalowalna sieć komunikacyjna w czasie rzeczywistym. Dzięki ponad 15 punktom obecności na całym świecie obsługującym 800 milionów aktywnych użytkowników miesięcznie i niezawodności na poziomie 99,999%, nigdy nie będziesz musiał martwić się o przestoje, limity współbieżności lub jakiekolwiek opóźnienia spowodowane skokami ruchu.

Poznaj PubNub
-------------

Sprawdź [Live Tour](https://www.pubnub.com/tour/introduction/), aby zrozumieć podstawowe koncepcje każdej aplikacji opartej na PubNub w mniej niż 5 minut.

Rozpocznij konfigurację
-----------------------

Załóż [konto](https://admin.pubnub.com/signup/) PubNub, aby uzyskać natychmiastowy i bezpłatny dostęp do kluczy PubNub.

Rozpocznij
----------

[Dokumenty](https://www.pubnub.com/docs) PubNub pozwolą Ci rozpocząć pracę, niezależnie od przypadku użycia lub [zestawu SDK](https://www.pubnub.com/docs).