Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open more actions menu

Repository files navigation

netler logo

Build Status NuGet

Netler.NET

A library for cross-process method calls over TCP. Designed for calling .NET methods from Elixir (see hexdocs.pm/netler), and usable anywhere you need fast binary RPC between processes. All messages are serialised with MessagePack.

Getting Started

dotnet add package Netler.NET

Server

Basic route registration

using Netler;

var server = Server.Create(config =>
{
    config.UsePort(5544);
    config.UseRoutes(routes =>
    {
        routes.Add("Add", param =>
        {
            var a = Convert.ToInt32(param[0]);
            var b = Convert.ToInt32(param[1]);
            return a + b;
        });
    });
});

await server.Start();

Typed routes with AddTyped

AddTyped infers parameter and return types from the lambda. The C# compiler enforces the types; the wire format is unchanged.

config.UseRoutes(routes =>
{
    routes.AddTyped("Add",    (int a, int b) => a + b);
    routes.AddTyped("Double", (int x) => x * 2);
    routes.AddTyped("Ping",   () => "pong");
    routes.AddTyped("Log",    (string msg) => { /* void handler */ });
});

Explicit composition with Params.Decode

Params.Decode wraps a typed delegate into the Func<object[], object> signature that IRoutes.Add expects. Useful when you want to separate the handler from the route registration, or pass an existing method reference.

static int Add(int a, int b) => a + b;

config.UseRoutes(routes =>
{
    routes.Add("Add",    Params.Decode<int, int, int>(Add));
    routes.Add("Double", Params.Decode((int x) => x * 2));
    routes.Add("Ping",   Params.Decode(() => "pong"));
});

Complex types

Any type annotated with [MessagePackObject] can be used as a parameter or return value.

using MessagePack;

[MessagePackObject]
public class EchoRequest  { [Key(0)] public string Text { get; set; } }

[MessagePackObject]
public class EchoResponse { [Key(0)] public string Message { get; set; }
                            [Key(1)] public int    Length  { get; set; } }

config.UseRoutes(routes =>
{
    routes.AddTyped("Echo", (EchoRequest req) =>
        new EchoResponse { Message = req.Text, Length = req.Text.Length });
});

Monitoring the client process

The server can watch a client OS process and react automatically when it exits.

Server.Create(config =>
{
    config.UsePort(5544);
    config.UseClientPid(clientProcessId);
    config.UseClientDisconnectBehaviour(ClientDisconnectBehaviour.DisposeServer);
});
ClientDisconnectBehaviour Effect
ShutdownApplication Calls Environment.Exit(0) — default
DisposeServer Stops the server; application keeps running
KeepAlive No action

Custom logger

using Microsoft.Extensions.Logging;

ILogger logger = loggerFactory.CreateLogger<MyApp>();

Server.Create(config =>
{
    config.UsePort(5544);
    config.UseLogger(logger);
    config.UseRoutes(routes => { /* ... */ });
});

Client

Typed calls (recommended)

using Netler;

using var client = new Client(5544);

var sum  = await client.InvokeAsync<int>("Add",    new object[] { 2, 3 });
var pong = await client.InvokeAsync<string>("Ping", new object[0]);

// Complex return type — EchoResponse must carry [MessagePackObject]
var reply = await client.InvokeAsync<EchoResponse>("Echo",
    new object[] { new EchoRequest { Text = "hello" } });

Untyped calls

var raw = await client.InvokeAsync("Add", new object[] { 2, 3 });
var sum = Convert.ToInt32(raw);

Remote to another machine

using var client = new Client("192.168.1.10", 5544);

Error handling

When a route handler throws an unhandled exception on the server, the client receives a RemoteInvokationFailed exception containing the server-side error message.

using Netler.Exceptions;

try
{
    await client.InvokeAsync("Divide", new object[] { 10, 0 });
}
catch (RemoteInvokationFailed ex)
{
    Console.WriteLine($"Server error: {ex.Message}");
}

About

Server and Client for cross-process method calls over TCP using MessagePack

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.