2

I'm evaluating whether nats.io is an okay replacement for Firebase Cloud Messaging or not.

This is my started code which uses nats-android library

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.google.android.material.button.MaterialButton;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import io.nats.client.Connection;
import io.nats.client.Duration;
import io.nats.client.Message;
import io.nats.client.Nats;
import io.nats.client.Options;
import io.nats.client.Subscription;

public class MainActivity extends AppCompatActivity {

    private Connection nc;
    private MaterialButton btnPublish, btnSubscribe;

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

        btnPublish = (MaterialButton)  findViewById(R.id.btn_nats_publish);
        btnSubscribe = (MaterialButton) findViewById(R.id.btn_nats_subscribe);

        Options.Builder oBuilder =
                new Options.Builder()
                        .server(Constants.NATS_BASE_URL)
                        .reconnectWait(Duration.ofMinutes(3)).maxReconnects(-1);
        Options opts = oBuilder.build();

        try {
            nc = Nats.connect(opts);
        }
        catch (InterruptedException ie){
            Log.d("NATS", "InterruptedException at MainActivity: "+ie.getMessage());
        }
        catch (IOException ioe){
            Log.d("NATS", "IOException at MainActivity: "+ ioe.getMessage());
        }
        if (!NotificationService.natsSvcIsRunning){
            Intent start = new Intent(MainActivity.this.getApplicationContext(), NotificationService.class);
            start.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            start.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
            MainActivity.this.startService(start);
        }

        btnPublish.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("NATS", "Trying to publish...");
                nc.publish("rcpt", "msg".getBytes(StandardCharsets.UTF_8));
            }
        });

        btnSubscribe.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Subscription sub = nc.subscribe("topic");
                Log.d("NATS","subscribing to "+sub.getSubject());
                Message msg = null;

                try {
                    msg = sub.nextMessage(Duration.ZERO);
                    String response = new String(msg.getData(), StandardCharsets.UTF_8);
                    Log.d("NATS","got request "+response+" from "+msg.getReplyTo());
                }
                catch (InterruptedException ie){
                    Log.d("NATS", "InterruptedException: "+ie.getMessage());
                }
            }
        });
    }
}

Running the code, here's the logcat output

2022-01-11 15:54:17.689 16748-16748/com.anta40.app.natsdemo D/NATS: IOException at MainActivity: Unable to connect to NATS server.
2022-01-11 15:54:17.711 16748-16748/com.anta40.app.natsdemo D/NATS: NotificationService onCreate() method.
..
..
..
2022-01-11 15:54:17.800 16748-16787/com.anta40.app.natsdemo D/NATS: nats server connection nats: connection opened
2022-01-11 15:54:17.801 16748-16774/com.anta40.app.natsdemo D/NATS: subscribing to req_auth

I'm aware that:

  1. There's an IOException occured in MainActivity
  2. NATS subscription is succesfully done in NotificationService

Not surprisingly, when you click the subscribe button, a NullPointerException will be triggered.

My question is how to create NATS connection in MainActivity properly?

anta40
  • 6,511
  • 7
  • 46
  • 73
  • From my experience `Nats.connect()` does not reconnect when it throws an error, so either you will need to retry creating the connection or you could pass in the connection (directly or via a service) and reuse it in different parts of your application, depending on your use case – Lennart Stoop Jan 11 '22 at 18:49

0 Answers0