Skip to content

Momy93/NubChat

Repository files navigation

Introduction

Nubchat is an Android app that let you communicate with other android smartphones, or dev boards like Arduino, RaspberryPi and all the devices that support PubNub API's.
To use this app you'll need a subcribe key and publish key from https://pubnub.com, and enable "STORAGE & PLAYBACK" AND "STREAM CONTROLLER".
It's available on Google play store https://play.google.com/store/apps/details?id=com.mohamedfadiga.nubchat

Usage

You can sent two type of message from your devices. All message are in JSON format:

  • Simple text message

{ "sender": "YourDeviceName", "type": 0, "text": "Dattebane!" }

  • Location message

{ "sender": "YourDeviceName", "type": 3, "text": "Here I am!", "latlon":"45.321489,11.369874" }

Where latlon represents GPS coordinates: latitude,longitude

There are many things you can do with this app. The main purpose is that you have some devices that will communicate, and do actions or give you informations about themselves when you write to them. You can find an example here https://www.hackster.io/Momy93/nubchat-chat-app-for-devices-and-humans-with-pubnub-bad66c


![description](https://raw.githubusercontent.com/pluralsight/guides/master/images/f40d498e-9a95-410e-b4ab-d82c2c38f4d5.jpg)

description

description

description

How it works

For the first usage, you have to chose a username and insert your pubnub keys.
Of course these keys are personal, and should not share them with other people.

"So, what if i want to chat with my friend Mark?"

This app is designed for communicating with your devices, and an Android smartphone is a device, but used by another person.
So if you want to chat with Mark you'll have to provide him your keys.
Otherwise if you want to use NubChat as a normal chat app for smartphones, hard code your keys in the app souce.

The username you chose, is not your pubnub email or username, it's just a name you chose to receive messages on the current device.
Once you make this first setup, you can start using tha app.
You can edit your username and PubNub keys when you want on Menu->Seetings.

With the "+" Button you can add new channel. You'll be prompt to chose the channel name and set if it's a public or private. Public and private channel are not functions from Pubnub. This logic is created inside the app using pubnub API's. When you add a new channel, its informations are store on a local database on your smartphone.
To explain you well how the app works, let say you installed it and you chose "Bob" as username.
Let's add a private channel called RaspberryPi.

description

As already said data about this new channel are stored in the local database. The databasse's channels table structure is something like this:

name channel_type channel_status last_rec_id last_add_id
RaspberryPi 0 0 -1 -1

name: the name of the channel.
channel_type: 0 for private channel and 1 for a public one.
channel_status: not used in this first release of the app.
last_rec_id: the id of the last received message (from our Raspeberry)
last_add_id: the id of the last message added to this channel, either sent or received.

last_rec_id and last_add_id are -1 because the channel is empty yet. when we send a message the app use pubnub publish function.

A message sent by the app has the following structure:

{
  "channelName": "RaspberryPi",
  "sender": "Bob",
  "type": 0,
  "text": "Dattebayo!",
  "timetoken": 14858572070330000
}

Type for now can be 0 (pure text message) or 3 (location message). in the Message class you can see future types that will be available:

public static final int TEXT = 0, IMAGE = 1, FILE =2 , GMAPS = 3;

When sending a message to the app from your device, you can have two type of mesage:

{
  "sender": "RaspberryPi",
  "type": 0,
  "text": "Dattebane!"
}


{
  "sender": "RaspberryPi",
  "type": 3,
  "text": "Here I am!",
  "latlon":"45.321489,11.369874"
}

When RaspberyPi wants to send me a message, it will send it to "Bob" channel, and as I am a subscriber, I will receive it. Even if I didn't added the private Channel, if someone publish a message direclty on my channel, I receive it.

For public channel, it is not efficient to subscribe to all the channels. Pubnub guidlines says:

Currently, we recommend you use channel multiplexing for up to 10 (ten) channels. If your app requires a single client connection to subscribe to more than 10 channels, we recommend using channel groups. But you can subscribe to 50 channels from a single client.

So I'm using a channel group. Lets say we added two new public channels: Group1 and Group 2:

name channel_type channel_status last_rec_id last_add_id
RaspberryPi 0 0 7 5
Group1 1 0 -1 -1
Group2 1 0 -1 -1

Now what I do is to add Group1 and Group2 to a channel group, so I just need to subscribe to it, in order to receive messages from the these channels. Adding channels to a channel group doesn't mean that they are logically inserted in the group. You can still subscribe and publish to this channel. What the channel group does is something like subscribe to all the channel you added, and send you back the messages he receive from them. In my case I add public channels to a channel group that has the same name of my channel (Bob).

pubNub.subscribe()
            .channelGroups(Collections.singletonList(username))
            .channels(Collections.singletonList(username))
            .execute();

As you can see subscribing to channels and to channel group has two separated methods, and I'm giving them always "Bob" as a parameter. When the subscribe method calls my calback, it tells me if someone publish directly on channel "Bob", or someone published on a channel added to the channel group called "Bob". This is the callback called when there is a new message:

@Override
public void message(PubNub pubnub, PNMessageResult r){
    DatabaseHelper db = DatabaseHelper.getInstance(service);
    JsonObject o = r.getMessage().getAsJsonObject();
    String sender = o.get("sender").getAsString();
    if(sender.equals(username))return;
    String channelName = r.getSubscription();
    if(channelName == null)channelName = sender;
    else channelName = r.getChannel();
    service.newMessage(db.saveMessage(o, channelName, r.getTimetoken()));
}

If a message has been sent to a public channel, r.getSubscription()) value could be for example "Group1" or "Group2". So, when r.getSubscription() give me a null pointer, I know that the message has been published directly on "Bob" channel and not on a public channel.

When your device goes online after being offline, the app uses history funcition to get messages you missed while you were offline.
This time I have to call the history function for all the public channels because channel group hasn't history capability. Maybe there is a better way to do this anyway but I don't get by now. For private channels instead, I just need to call history on my own channel (Bob).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages