Get Started: Real-time, Multi-Device Synchronization

Estimated reading time: 11 minutes

In this part, we will learn about synchronizing messages and user data on multiple devices with mesibo.

Note, to use the synchronization feature, you need to use the mesibo On-Premise, which allows you to store all the messages in your data center.

Prerequisites

You MUST go through the following prerequisites before you read further.

Multi-Device Synchronization

Mesibo stores your app’s messages on the server till they are delivered. Once the app receives messages, they are stored on the local device database so that your app can quickly access them later (both when online and offline). This is a very optimal approach used by many popular and high user density apps like Whatsapp.

However, when the user moves to a new device, they cannot access the local database on the previous device and hence cannot view old messages unless old messages are retrieved somehow.

One way to retrieve old messages is to instruct the server to retain all the messages even after they are delivered. This will allow the app to redownload (sync) older messages to the new device. mesibo provides sync() APIs so that you can download all the messages from the server to the local database and then use normal mesibo read APIs to read messages as required.

To use sync() APIs, you need to use mesibo On-Premise, which allows you to store all the messages in your data center.

Real-time, On-demand sync

Device Sync

Depending upon the nature of your app, the number of messages a user exchanges could be large and so is the sync bandwidth and the time. Hence, mesibo provides you on-demand incremental syncing of only the messages a user is viewing instead of downloading it all at once.

In a typical UI implementation, the user looks at the latest messages first and then scrolls up to view older messages. You can utilize this behavior to enable your app to sync in real-time without waiting and also without unnecessarily downloading messages in advance, as the user scrolls up.

How to use On-Demand Synchronization effectively

As explained above, it is recommended to use synchronization API on-demand when you run out of messages in the local database. A typical usage would be to use it along with the read() API. The read() API returns the number of messages that were read. If the number of messages is less than you requested, use the sync() API to synchronize the local database with the server. The onSync() function is called with the number of messages synced when sync() is completed.

Sync Flow

Step-1: Create a read session object for a selected user or group.

In Android,

Mesibo.ReadDbSession mReadSession = new Mesibo.ReadDbSession(mRemoteUser, 0, null, this);

In iOS,

mReadSession = [MesiboReadSession new];
[mReadSession initSession:mRemoteUser groupid:0 query:nil delegate:self];

Step-2: Call read by specifying the number of messages you want to read from the local database.

Let’s say we want to display 10 messages.

In Android,

int readCount = 10; 
int result = mReadSession.read(readCount);

In iOS,

int readCount = 10;
int result = [mReadSession read:readCount]; 

Once you call read(), it reads the local database and checks if there are messages for the user/group. If there are, you will be getting those messages through Mesibo_OnMessage, and read will return the number of messages read. See the section on Read APIs to know more.

Step-3: Check if you have sufficient messages

If the readCount that you are requesting is less than the number of messages available in the database(for that user/group), it means you have sufficient messages in your local database. For example, if you tried to read 10 messages and you have 10 messages in the database, it’s all good. read() will return 10. You can display 10 messages on the screen.

Now, if the user scrolls to the top of the chat and wants to view older messages we need to load more messages from the database. Let’s say we want to load 10 more messages from the database. We call read again. Remember, we have previously read 10 messages from the database.

If you again try to read say 10 more messages, there are two possibilities:

  • There are sufficient messages in your database. If there are 10 more messages in the database for the selected user/group, read() will again return 10 and we will continue to display 10 more messages(older than the ones currently displayed) on the screen.

  • You have run out of messages in your database. If 10 more messages are NOT available for the selected user or group, read will return a value < 10. i.e. Less than your requested readCount. You need to synchronize messages.

Note: If your database is empty(For example: when the user moves to a new device), read will return 0 which will be less than the number of messages you tried to read. So, you have the second case where you need to synchronize from your server.

In the second case, where you have run out of messages on your database you need to synchronize more messages from your server. Say, read returned 4 messages. But, you tried to read 10 messages. You need 6 more messages. You can display 4 messages, and asynchronously request 6 (or more) messages from your server using sync.

Step-4: Synchronize messages

The sync method takes two parameters:

  • count The number of messages you want to synchronize
  • Sync Listener The listener context that implements Mesibo_onSync. (Slightly different in Javascript. See sync handler)

Note that a call to read() is synchronous while the call to sync() is asynchronous. The result of your sync the request will be available through the listener Mesibo_onSync. The call to sync checks messages stored on the mesibo server and transfers those messages to your local database. The number of messages that have been synced will be available as a parameter count in the OnSync listener. You can read count number of messages using read(). To learn more about sync see API Reference Manual

For example, in Android,

int readCount = 10;
int result = mReadSession.read(readCount)
if(result < readCount){
	mReadSession.sync(readCount - result, this);
}

In iOS,

int readCount = 10;
int result = [mReadSession read:readCount];
if(result < readCount) {
        [mReadSession.sync:readCount - result SyncListener:self];
}

Step-5: Read and display messages after the sync is complete

If there are older messages available on the server database, the user/group you have requested sync will give you the number of messages you requested for. In our example, we requested 6 older messages. Once sync completes, your local database will be updated with 6(or lesser) older messages. The number of messages synced will be available through the OnSync listener. You can read these messages and display them.

@Override
public void Mesibo_onSync(int count) {
	// count number of messages have been synced
	// You can now read these messages
	if(count <= 0) return;
	mReadSession.read(count);
}

In iOS,

-(void) Mesibo_OnSync:(int)count {
        // count number of messages have been synced
        // You can now read these messages
        if(count <= 0) return;
       	[mReadSession read:count] 

}

Restoring messages on a new device

When the user moves to a new device, initially your database may be empty. In this case, read will return 0 which will be less than the number of messages you tried to read. So, you need to synchronize messages. Here, are some code examples for doing this.

In Android,

int c = mReadSession.read(100);
if(c == 0){
	// No messages available for this user in local database
	// Synchronize from server and check again
	// Sync for say 100 messages
	mReadSession.sync(100, this);
}

@Override
public void Mesibo_onSync(int count) {
	if(count <= 0) return;
	mReadSession.read(count);
}

In iOS,

int c = [mReadSession read:100];
if(c == 0) {
	// No messages available for this user in local database
        // Synchronize from server and check again
        // Sync for say 100 messages
        [mReadSession.sync:100 SyncListener:self];
}

-(void) Mesibo_OnSync:(int)count {
        if(count <= 0) return;
       	[mReadSession read:count] 
}

Using sync API in Javascript

In Javascript, on calling read, the read handler on_read is called with the number of messages read, as a parameter. You can then call getMessages() to get your array of messages. You can refer to the Javascript section on Read APIs to know more.

When sync is complete, the on_sync handler will be called where you can then call read().

let rSession =  mesibo.readDbSession(peer, groupid, null,
	function on_read(count) {
		if(count < this.readCount){
			//Run out of messages
			this.sync(this.readCount - count,
				function on_sync(i){
					if(i > 0){
						this.read(i);
						let msgs = this.getMessages();
						// Display messages
					}
			});
			return;
		}

		let msgs = this.getMessages();
		//Display Messages if you have sufficient messages
		
	});

rSession.readCount = 10;
rSession.read(10);

Synchronizing Message Summary

In the previous section, we learned to synchronize messages for a selected user/group. In a typical app flow, you may want to display the message summary first. For example, in a messaging app, you may first need to show a list of all users you have sent/received messages. In this case, you need to read messages in summary mode.

To synchronize message summary, follow the same steps as above for reading messages but create a summary session instead. For examples, see Reading Messages

mesibo, android, ios