Team XSockets.NET

RPC/RMI

How to define methods on the client that the server can call

You define the methods per Controller since one connection can communicate over several Controllers

Client

The example below creates a listener for ChatMessage and it expects the data to be a string.

conn.Controller("chat").On<string>("chatmessage", data => Console.WriteLine(data));

Server

The server code for the examples with the ChatModel can look like

//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;

this.InvokeToAll("I am Yogi the gummi bear","chatmessage");

Methods without parameters

If the method you're handling does not have parameters just use the non generic On method.

Server

//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;

public class Chat : XSocketController
{
    public async Task CallAllClients()
    {
        await this.InvokeToAll("test");
    }
}

Note: You can of course use InvokeTo<T> or Invoke as well

Client

conn.Controller("chat").On("test", () => Console.WriteLine("Test Was Called"));

Methods with parameters, specifying parameter types

If we have a complex object being sent from the server, like the ChatModel we can of course just do like this

conn.Controller("chat").On<ChatModel>("chatmessage", data => Console.WriteLine(data.UserName + " - " + data.Text));

Server

The server code for the examples with the ChatModel can look like

//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;

this.InvokeToAll(new ChatModel{Name="Yogi", Text="I am a gummi bear"},"chatmessage");

Methods with parameters, specifying dynamic objects for the parameters

As an alternative to specifying specific types to the On method, you can specify parameters as dynamic objects.

conn.Controller("chat").On<dynamic>("chatmessage", data => Console.WriteLine(data.Text));

Note: Dynamic keyword will (currently) not exist in clients for Android/iOS. Note: Dynamic keyword does not exist in .NET 3.5 and earlier.

Server

The server code for the examples with the ChatModel can look like

//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;

this.InvokeToAll(new ChatModel{Name="Yogi", Text="I am a gummi bear"},"chatmessage");

Methods with parameter of type IMessage

If you for some reason want the actual IMessage sent from the server to the client you can specify IMessage as the type. You will then get the complete object that the client received!

conn.Controller("chat").On<IMessage>("chatmessage", o => Console.WriteLine("{0}, {1} {2}, {3},",o.Controller, o.Topic, o.Data, o.MessageType);

If you know the type contained in the Data part of the IMessage you can use Extract to get the value.

//example extracting the JSON into a specific type
var chatModel = o.Extract<ChatModel>();

Server

The server code for the examples with the ChatModel can look like

//using XSockets.Core.XSocket;
//using XSockets.Core.XSocket.Helpers;

this.InvokeToAll(new ChatModel{Name="Yogi", Text="I am a gummi bear"},"chatmessage");

How to remove a handler

When you want to dispose of a handler you have to remove it from the Controller where it was used.

var listener = conn.Controller("chat").On<string>("chatmessage", data => Console.WriteLine(data));   

conn.Controller("chat").DisposeListener(listener);

How to send to server methods from the client

To call a method on the server, use the Invoke method on the Controller.

If the server method has no return value, use the non-generic overload of the Invoke method.

Server - method without return value

//using XSockets.Core.XSocket;

public class Chat : XSocketController
{
    protected string UserName {get;set;}
    public void SetUserName(string userName)
    {
        this.UserName = userName;
    }
}

Client - calling a method that has no return value

conn.Controller("chat").Invoke("setusername", new {userName = "Steve"});

How to call a server side method and wait for the result

If the server method has a return value, specify the return type as the generic type of the Invoke method.

Server - for a method that has a return value

public IEnumerable<Stock> GetStocks()
{
    return _stockTicker.GetAllStocks();
}

The Stock class used for return value

public class Stock
{
    public string Symbol { get; set; }
    public decimal Price { get; set; }
}

Client - calling a method that has a return value in a synchronous method

var stocks = await conn.Controller("stockticker").Invoke<IEnumerable<Stock>>("GetStocks");
foreach (Stock stock in stocks.Result)
{
    Console.WriteLine("Symbol: {0} price: {1}\n", stock.Symbol, stock.Price);
}

If there is no response for 30000 ms there will be a TimeoutException so you should wrap the synchronous call like:

try
{
    var stocks = await conn.Controller("stockticker").Invoke<IEnumerable<Stock>>("GetStocks");
    foreach (Stock stock in stocks.Result)
    {
        Console.WriteLine("Symbol: {0} price: {1}\n", stock.Symbol, stock.Price);
    }
}
catch (AggregateException ae)
{
    ae.Handle((x) =>
    {
        if (x is TimeoutException)
        {
            //The communication did not respond within given time frame
            //Handle it...
            return true;
        }
        //Another exception handle it... or return false to stop app
        return false;
    });
}

Of course you can set the default 30000 ms to be longer or shorter if needed. Just pass in your timeout as a parameter in the call like

//Timeout will now be 5 seconds
var stocks = await conn.Controller("stockticker").Invoke<IEnumerable<Stock>>("GetStocks",5000);

results matching ""

    No results matching ""