Real-time Messaging

Welcome to the Facebook Instant Games SDK Tutorials. This series of tutorials covers many aspects of using the Facebook Instant Games SDK.

In this tutorial we will take a look at working with real-time messaging using the Facebook Instant Games SDK.

What is Real-Time Messaging?

Real time messaging is the ability to send messages between users that are playing the same game at the same time. Unfortunately, Facebook Instant Games does not offer such a feature, so we have to look towards implementing something that can handle this ourselves.

The closest Facebook gets to this is turn based messages via updateAsync(), which is ok for turn based games, however the system is flawed in that the entry point data sent to a context cannot be collected in real-time, it can only be collected when the user closes and re-launches the game.

Simple Messaging System

Across a number of my games I have had the need to send data around different players in real-time. For example, in the game Lets Bounce, I need to let players know the result of a challenge that they sent to their friends, but I need to know as soon as this occurred. I don’t want the player to have to exit the game and re-launch in the challenge context to find the result. This for me is where Faceboook Instant Games really does fall down, but luckily its an easy fix.

I developed a fast free open source simple messaging system using node.js, express and redis which you can install to your server and use.

This messaging system is easy to use:

[sourcecode language=”js”]
Send a message to a user of a specific game
http://your_host:8080/msg?t=&game1=a&u=1234&c=s&d=message1

Broadcast a message to a list of users of a specific game
http://your_host:8080/msg?t=&game1=a&u=1234&_2345_3456c=s&d=message1

Get all pending messages for a specific user of a specific game
http://your_host:8080/msg?t=&game1=a&u=1234&c=g
[/sourcecode]

You can pass the following parameters on the Url:

  • t is verification token
  • d is the message
  • g is game id
  • u is user id
  • m is for multiple user id’s which is an underscore separated list of users for broadcast
  • c is command which can be:
    • s command is set data
    • g command is get data

The idea is that the user will poll the simple messaging system server to check for new incoming messages. Lets wrap up access to the simple messaging system into some easy to use functions:

[sourcecode language=”js”]
var Backend = {};

// Send a get request
Backend.SendGetRequest = function(url, callback)
{
var req = new XMLHttpRequest();
req.onreadystatechange = function()
{
if (callback != undefined && req.readyState == 4)
callback(req);
}
req.open("GET", url, true);
req.send();
}

// Send a message to specific user
Backend.SendMessage = function(game_id, to_id, data, done_callback)
{
var url = "https://yourdomain.com/msys?c=s&t=<your token>";
url += "&g=" + game_id;
url += "&u=" + to_id;
url += "&d=" + encodeURIComponent(JSON.stringify(data));
Backend.SendGetRequest(url, function(response) {
if (done_callback !== undefined)
done_callback(response);
})
}

// Send a message to a list of users
Backend.SendMessageMulti = function(game_id, recipients, data, done_callback)
{
var users = "";
var len = recipients.length;
for (var t = 0; t < len; t++)
{
users += recipients[t];
if (t < (len – 1))
users += "_";
}
var url = "https://yourdomain.com/msys?c=s&t=<your token>";
url += "&g=" + game_id;
url += "&m=" + users;
url += "&d=" + encodeURIComponent(JSON.stringify(data));
Backend.SendGetRequest(url, function(response) {
if (done_callback !== undefined)
done_callback(response);
})
}

// Send all pending messages from the server
Backend.GetMessages = function(game_id, player_id, done_callback)
{
var url = "https://yourdomain.com/msys?c=g&t=<your token>";
url += "&g=" + game_id;
url += "&u=" + player_id
Backend.SendGetRequest(url, function(response) {
if (response.status == 200)
{
var data = decodeURIComponent(response.responseText);
var obj = JSON.parse("[" + data + "]");

if (done_callback !== undefined)
done_callback(obj);
}
else
{
if (done_callback !== undefined)
done_callback();
}
})
}
[/sourcecode]

Leave a Reply