1. Home
  2. Docs
  3. Documentation
  4. Plugins
  5. Remote method invocation

Remote method invocation

Probably the largest selling point is, SB enables invocation of methods by using static typing. The client and the server both can invoke methods on the other side. There are some differences which will be covered below.

Client to Server invocation

In order to invoke the method remotely, first you must get the proxy. This proxy is a wrapper, and, in case of client, can be acquired by executing the IClient method GetProxy<TPlugin>.

To continue the previous example. When the client connects to the server, method Sum is invoked. This is done in two simple lines of code:

private void Client_OnConnected()
{
    Console.WriteLine("Connected!");
    var awaitedProxy = this.client.GetProxy<ICalculatorServer>(MethodCallStyle.WaitResponse);
    int sum = awaitedProxy.Sum(1, 2);
    Console.WriteLine($"Got response: {sum}");
}

Notice the parameter in GetProxy method. This is enum MethodCallStyle. Possible values are:

  • WaitResponse – current thread will wait for the response from the remote party, or a timeout, which is set to 5 seconds
  • FireAndForget – the thread will continue execution, and return the default value for that return type – in this case that would be 0

Tasks

It is possible to use tasks for certain async methods. The invocation of async methods is similar to the synchronous methods, but there is one difference: when using WaitResponse call style, the current thread will send the request, and then continue the execution until the task is awaited.

As a concrete example, a method is added to the ICalculatorServer:

[SBMethod(2)]
Task<int> GetRandomNumber(int min, int max);

The implementation of the method (in CalculatorServer file):

public async Task<int> GetRandomNumber(int min, int max)
{
    // lets wait for some random time, and then return a random number
    var random = new Random();

    // wait up to 500ms
    var delayTime = random.Next(500);

    // calculate response before awaiting task completion
    // there is no reason to capture state of three values (min, max, random)
    // when only one can be captured (response)

    // for more info, read about async/await and state capturing
    var response = random.Next(min, max);

    await Task.Delay(delayTime);
    return response;
}

Client is programmed to invoke this method when a connection is established. Client side invocation of server method :

private async Task GetRandomNumberAsync()
{
    var awaitedProxy = this.client.GetProxy<ICalculatorServer>(MethodCallStyle.WaitResponse);
    var task = awaitedProxy.GetRandomNumber(1000, 5000);
    // the request is now sent to the server, and other work can be done before awaiting the response
    Console.WriteLine("Waiting for the async response");

    // sleeping a bit - emulating some job
    await Task.Delay(1000);

    // await the task - if the result is not yet available, this will wait until it is
    // or a timeout occurred (currently set to 5 seconds), in which case, exception will be thrown
    var randomNumber = await task;
    Console.WriteLine($"Server returned the random number: {randomNumber}");
}

Server to client invocation

Invoking the method on a client is done in the same manner. The difference is in getting the proxy. The server has two methods to get proxy:

  • GetProxy<TProxy>(string username, MethodCallStyle callStyle) – gets a proxy which invokes a method on a single user. It is possible to specify call style and use WaitResponse – but that is not recommended to do on a server – ever.
  • GetProxy<TProxy>(params string[] usernames) – gets a proxy which invokes a method on multiple users. Using this proxy always implies FireAndForget method call style.

For more info and concrete examples, see
Next step: Available server interfaces.

Was this article helpful to you? Yes No

How can we help?