WCF .Net API Tutorial


Glossary

Device Capabilities
The capabilities of the user's currently online device, e.g. screen size and support for markup.
External Application
A third-party Mxit application hosted externally to the Mxit platform.
External Application API
A Net.TCP Microsoft WCF interface providing access to the Mxit platform for application developers.
MXit Client
A Mxit client application running on e.g. a mobile device or PC that is used by a user to access the Mxit platform.
MXit ID
The identifier a user uses to log in to Mxit. External applications only ever uses the User ID and never the Mxit ID.
MXit Platform
The environment to which Mxit clients connect and the External Application API provides access.
Presence
A status indicating whether a user is online or offline.
User ID
An identifier that identifies the Mxit user uniquely, internally to the Mxit platform. External applications only ever uses the User ID and never the Mxit ID.

Introduction



The Mxit External Application API is aimed at solo software developers or companies with a software development competency who wish to provide rich and dynamic services to Mxit users. The technology is built on Microsoft's WCF framework, which is an extension of the .NET framework.

In order to use the API, you need the following:

The Mxit External Application API web service uses WCF's Net.TCP binding. We chose this to maximise throughput and minimise latency. That means that the web service can only be consumed by WCF supported services and frameworks.

It is vital for application developers to test their application on a variety of mobile devices to ensure correct rendering of the user interface.

Connecting your service to the External Application API

Setting up a new project

Install the External Application SDK, open Visual Studio and create a new project of your choice. This will normally be a Windows service or class library project, but for testing, a console application will suffice. The sample code provided here uses C#.

Next, you need to add MXitExternalAppSDK.dll and System.Drawing.dll as a references. Find the installation location of the MXit library by opening it from your start menu (it will install to MXit Lifestyle\MXit External Application SDK).

You're now ready to add a new service reference. Note that if you haven't added these references, the WSDL cannot be parsed in full and thus the full API won't be available. The endpoint's URI is http://externalappapi.mxit.com:9151/ExternalAppAPI/Comms/mex. We'll use ExternalAppAPI as the namespace. If you are using one of the examples included in the SDK download, be sure to update this service reference before continuing.

Implementing the callback interface

Before a connection can be established, you need to implement the API's CommsCallback interface. Create a new class to service the callbacks. Note the class attribute regarding concurrency: This attribute will ensure that your service utilises WCF's built-in threading mechanism and allow for full duplex communication.

using System.ServiceModel;
 
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
internal class Callback : ExternalAppAPI.CommsCallback
{
    // Empty class
}

Use Visual Studio to create the required event handlers automatically.

Connecting to the web service

Everything you need to connect is now set up. The following sample shows how to connect to the web service. A keep-alive packet should be sent every few minutes to keep your application's API session alive. You can also add functionality to reconnect in case of a lost connection (not shown here).

namespace ConsoleApplication
{
    using System;
    using System.ServiceModel;
    using System.Threading;
    using MXit;
 
    public class Program
    {
        // Client connection
        static ExternalAppAPI.CommsClient client;
 
        public static void Main(string[] args)
        {
            try
            {
                // Create a new instance of the class that implements the API's callbacks
                ExternalAppAPI.CommsCallback callback = new ExternalAppAPI.Callback();
                InstanceContext context = new InstanceContext(callback);
 
                // Create a new client connection
                client = new ExternalAppAPI.CommsClient(context);
                client.Connect("myservicename", "myservicepassword", SDK.Instance);
                Console.WriteLine("Connected");
 
                // Set up a keep-alive timer to keep the connection alive
                Timer keepAliveTimer = new Timer(new TimerCallback(KeepAlive),
                                                 null,
                                                 3 * 60 * 1000,
                                                 3 * 60 * 1000);
                Console.WriteLine("Press any key to disconnect . . .");
                Console.ReadKey(true);
 
                // Clean-up and disconnect
                keepAliveTimer.Dispose();
                client.Disconnect();
                client.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
 
        private static void KeepAlive(object stateInfo)
        {
            client.KeepAlive();
        }
    }
}

Handling messages and presence

All communication between applications and the API are sent as either message or presence packets. Messages can be plain text messages (e.g. chat messages) or rich messages containing special markup. There are different message types for sending and receiving messages: MessageReceived and IMessageToSend. The easiest way forward is to create the reply from the received message.

public void OnMessageReceived(MessageReceived messageReceived)
{
    IMessageToSend messageToSend = messageReceived.CreateReplyMessage();
 
    // ...
}

It is also possible to create your message without a prior request, e.g. to push a notification message to the user. Messages can only be pushed to users that has your application as a contact. Note that the user's presence status (i.e. whether being online or offline) will be unknown to the external application until the user has interacted with it. Until then, the implication is that the capabilities (screen size, support for markup, etc.) of the user's device will be unknown. The application shouldn't assume any capabilities, since the user could be online with a device different from the last time (e.g. switching between mobile and PC MXit client applications).

IMessageToSend msg = (IMessageToSend)MessageBuilder.CreateMessageToSend("theUserId");

Be sure to add the necessary references and using statements for the rest of the sample code in this tutorial to work correctly.

using MXit.Messaging;
using MXit.Messaging.MessageElements;
using MXit.Messaging.MessageElements.Actions;
using MXit.Messaging.MessageElements.Replies;
using MXit.User;

Your application would typically keep a user session, so be sure to clean up a user's session when you receive an offline presence packet. Offline presence is broadcasted to all of the user's contacts and services when the user logs off the MXit platform. Many users simply disconnects from the platform by terminating their MXit client abnormally. In such a case, the platform will timeout their session after roughly 15 minutes, given the user doesn't log in again during that time. Even though offline presence will always be sent under normal circumstances, you should still consider purging old or unused sessions as an optimisation.

public void OnPresenceReceived(Presence userPresence)
{
    if (!userPresence.IsOnline)
    {
        // Clean up session
        // ...
    }
}

Using markup and commands

The SDK provides you with a number of classes and methods to build messages. The MessageBuilder consists of a large number of appenders to add various elements. Note that a message's body or type never needs to be set by the application: The SDK will set it accordingly.

A MXit Client showing an inline image,
text markup, clickable link 

Text messages

Text messages are the simplest messages that can be sent to a user. This is achieved by simply appending text to your IMessageToSend. The font style and size can be manipulated and standard emoticons can be used.

messageToSend.Append("Hello World! ");
messageToSend.Append(Emoticons.Cool);
messageToSend.AppendLine();
messageToSend.Append("Some bold text", TextMarkup.Bold);
messageToSend.AppendLine();

Inline images

Inline images can be added to text messages. The flow, size and alignment can be adjusted in various ways.

Bitmap imageBitmap = new Bitmap(@"C:\Path\to\image.jpg");
IMessageElement inlineImage = MessageBuilder.Elements.CreateInlineImage(imageBitmap,
                                                                        ImageAlignment.Center,
                                                                        TextFlow.AloneOnLine,
                                                                        imageBitmap.Width,
                                                                        imageBitmap.Height);
messageToSend.Append(inlineImage);

Clickable links

Clickable links can be appended to messages in order to return a reply to the application when clicked by the user. Be sure to give the link an identifier unique to the application, so that it can identify the response.

IMessageElement link = MessageBuilder.Elements.CreateLink("Unique name to identify this link",          // Optional
                                                          "How the link must be displayed",             // Compulsory
                                                          "What to display when the link was clicked"// Optional
                                                          "Reply to return to the application");        // Optional
messageToSend.Append(link);

In order to parse the reply, the application must check that the message is of type MessageType.Normal. The message's body can then be checked for the reply message that was set for the link.

private bool IsMyLink(MessageReceived messageReceived)