Team XSockets.NET

Default Offline messages

There is helpers for using the IOfflineQueue but you can of course you the plugin framework to get the module and use it directly

var q = Composable.GetExport<IOfflineQueue>();

However, this section will show how to use the extensions for the IOfflineQueue

Saving messages while being offline

When a connection is closed you should tell the server that you would like it to save messages with specific topics. This is done by using the OfflineSubscribe helper. You might not wanna save all the messages that will arrive during your offline period (only specific topics).

Below we subscribe for the topics bar and baz while being offline

public override async Task OnClosed()
{
    await this.OfflineSubscribe("bar", "baz");
}

Note: You can also pass in a parameter that says for how long the messages will be saved. By default this value is 30 seconds, but if you implement something like MSMQ this might be infinite.

Retrieving messages when online

When we get back online we use the OnlinePublish helper to retrieve all messages that arrived while the connection was closed. Notice that we use the OnReopened method since that is when there might be messages stored for the client.

public override async Task OnReopened()
{
    await this.OnlinePublish();
}

Pushing messages to the OfflineQueue

By default messages are not stored on the OfflineQueue. So we have to push messages that we want to store for offline clients. This is done by using the Queue helper.

public async Task Bar(string m)
{
    await this.InvokeToAll(m, "bar");
    await this.Queue(DeliveryType.Rpc, m.AsMessage("bar"));
}

So first we send the message to all clients online, and then we store the message for clients that are currently offline and subscribing to the topic bar.

In a real implementation you would probably build a custom extension for this to avoid having 2 lines of code in the method. So something like below could be the complete solution.

Complete Sample

using XSockets.Core.XSocket;
using System.Threading.Tasks;
using XSockets.Core.XSocket.Helpers;
using XSockets.Core.Common.Protocol;
using XSockets.Core.Common.Socket;
using XSockets.Core.XSocket.Model;

public class Foo : XSocketController
{
    public override async Task OnClosed()
    {
        //Store messgages with the topics bar,baz while I am offline
        await this.OfflineSubscribe(60000,"bar", "baz");
    }

    public override async Task OnReopened()
    {
        //Get all messages (with topics bar,baz) that was sent while I was offline
        await this.OnlinePublish();
    }

    public async Task Bar(string m)
    {
        //Send to all online clients and store for clients being offline
        await this.InvokeToAndQueue(m, "bar");
    }
}

/// <summary>
/// Queue extentions
/// </summary>
public static class QueueHelpers
{
    public static async Task InvokeToAndQueue<T>(this T controller, object o, string topic) where T : class, IXSocketController
    {
        var m = new Message(o,topic,controller.Alias);
        await controller.InvokeToAll(m);
        await controller.Queue(DeliveryType.Rpc, m);
    }
}

Test The Sample

Testing this is pretty simple. Notice that I have set the storage timeout in the sample code to be 60 seconds so that I have enough time to play with Putty.

Open two Putty clients

We need 2 clients to be able to send some messages while one of them is offline. We will not close and reopen the clients with the same PersistentId. That would mimic a real life scenario, but in here we will only use the reserved topics to close and reopen a controller.

So the scenario will be that:

  • both clients is connected and use the Bar method in the Foo controller.
  • Then one of them will close the controller
  • The client being online send a message to the Bar method on the Foo controller
  • The client that closed the controller reconnects
  • The message that was sent while the client was offline will be sent to the client.

2 clients connect

We open 2 Putty clients and open the Foo controller by sending in foo|1|.

offline 1

Messages sent

The client on the top send a message Hello all and both client receive it

offline 2

One client closes the controller

The client at the bottom closes the Foo controller by sending in foo|3|

offline 3

The other client sends a message

The client on the top (still connected) send a message This will be stored in a offline queue and only the client on top receives that message instantly.

offline 4

The client reopens the controller & receives the message

Now the client at the bottom reopen/reconnect to the Foo controller by sending in foo|1|.

offline 5

The message that was stored for this client is sent out as soon as the reopen method get invoked.

results matching ""

    No results matching ""