How do I implement message (event) history?

Pusher makes it really easy to add real-time data and functionality to web, mobile and IoT apps. For use cases such as notifications and signalling, that data can be transient, where the data is only relevant for a short period of time. In other cases, such as activity streams or chat, data may need to be persisted and historical data is as important as the data delivered via real-time updates.

This article covers:

For this article it is assumed that your application persists messages prior to sending them via Pusher.

There is also a tutorial that covers an example in detail. You can read it on the Pusher blog

How and when to retrieve a history of messages

Being able to see a history of messages within a chat application provides context to the ongoing conversation. When you think about how you would add this functionality there are three choices that generally come to mind:

ChoiceWill it work?
1. Generate static HTML for the existing messages on the server No. Messages could be missed between the HTML being sent to the client and the subscription on the client taking place.
2. Fetch data upon connection No. The client hasn�t subscribed to the channel yet so any messages sent prior to the subscription could be missed.
3. Fetch data upon successful subscription Yep. This way you will get any new data via Pusher and can retrieve all historical data from your server.

You should fetch the historical messages from the server after successfully subscribing to the channel. The basic flow to achieve this is:

  1. The application loads
  2. Connect to Pusher
  3. Subscribe to the channel
  4. Bind to the pusher:subscription_succeeded event on the channel
  5. Bind to the new_message event to be notified when any new chat messages arrive via Pusher
  6. Upon successful subscription, retrieve the messages from the server
  7. Add the messages to the UI, ensuring that those messages are sorted and no duplicates exist from any messages that may have come in via Pusher during the retrieval

 

Retrieve Missed Messages Upon Subscription

The pusher:subscription_succeeded event is emitted from at channel once Pusher has acknowledge a subscription request. It is at that point at which historical messages should be retrieved.

In the following JavaScript example a retrieveHistory handler function will be called when the subscription has succeeded:

var pusher = new Pusher(PUSHER_CHAT_APP_KEY);
var chatRoom = this.pusher.subscribe('messages');
chatRoom.bind('pusher:subscription_succeeded', retrieveHistory);

The purpose of the retrieveHistory function is to fetch messages from your server. As an example, the following code will make an AJAX call to retrieve the chat message history:

function retrieveHistory() {
  $.get('/messages').success(function(response) {
    // TODO: extract messages from the response
  });
},

In this example the /messages endpoint would need to return a number of existing change messages. How it does that an how many it returns depends on your solution.

From here you need to add those messages to your application UI.

 

Adding Historical Messages to the UI

Now that the existing chat messages are being returned to the client they need to be shown in the UI.

When adding them to the UI it�s important to check two things:

  1. That duplicates don�t occur
  2. The ordering of messages in the UI is correct

The suggested solution to this is to have a sequence ID for each message so it�s very easy to detect duplicates and determine the correct order of messages. If you are using a database solution, the Primary Key for each message within your database may be sufficient.

 

How to retrieve messages missed during periods of network instability

Sometimes a client will lose Internet connectivity. When that happens new messages won�t be able to be delivered to that client.

The Pusher libraries maintain a list of channels that an application is subscribed to. Therefore, upon reconnection they can automatically re-subscribe to those channels. The benefit of this is that the functionality implemented to retrieve historical messages can also be used for this connectivity scenario because the pusher:subscription_succeeded event will once again be triggered resulting in the historical message retrieval logic being exercised.

The only addition that is required is for the call to the server to also pass an ID of the last message is presently has. This was previously referred to as a sequence ID that was to be used to detect duplicate messages and sort existing messages.

Taking the JavaScript example again, the retrieveHistory function can be updated as follows:

function retrieveHistory() {
  var lastId = getLastMessageSequenceId();
  $.get('/messages', {after_id: lastId}).success(function(response) {
    // TODO: add missed messages to the UI
  });
},

As before, you should check for duplicates and the order of your messages within the UI.

Conclusion

By following the techniques it is easy to use the events that the Pusher libraries expose to add historical data to an application and also fetch any missed messages during periods of network instability.

Was this article helpful?
1 out of 1 found this helpful
Haven't found what you were looking for?
Submit a ticket