Skip to content
A RPC TCP/Noise server and client for vibe.D
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
docpkg
docs
noise
src
.gitignore
.travis.yml
LICENSE_1_0.txt
README.md
dub.json
noise-c.patch
travis-ci.sh

README.md

vibe-rpcchannel

Coverage Status Build Status

This implements a simple D-only RPC mechanism for vibe.D. The library is designed to be generic and work with any transport stream. Easy to use wrappers are available for unencrypted TCP streams and vibe-noisestream encrypted noise channels.

The API documentation is available here.

Features

  • Events allow for server->client communication callbacks
  • Overloading for functions
  • API enables easy management of sessions and authentication
  • API is flexible enough to allow for reverse mode: The machine connecting to a remote machine can be the RPC server. This is useful for NATed machines.

Limitations:

vibe-rpcchannel is more of a method to quickly build client<->server messaging protocols than a general purpose RPC server. This means especially that only one RPC call can be processed at a time. Also there's only limited Exception handling: All server side exceptions map to an RPCException at the client. Use error return values instead.

A simple TCP server/client example

import vibe.d, vibe.rpcchannel;

abstract class API
{
    int request(int a);
    string request(string a);
    
    Event!(int) progress;
    Event!() timer;

    void startTimer();
    void stopTimer();


    @ignoreRPC void ignoredFunction() {};
    @ignoreRPC void ignoredEvent();
}

class APIServer : API
{
    bool _timerStop = false;

    static APIServer startSession(TCPConnection info)
    {
        // Use info for authentication
        return new APIServer();
    }
    
    override int request(int a)
    {
        progress.emit(1);
        progress.emit(2);
        progress.emit(3);
        return a;
    }

    override string request(string a)
    {
        progress.emit(4);
        return a;
    }

    override void startTimer()
    {
        runTask(()
        {
            while (!_timerStop)
            {
                timer.emit();
                sleep(100.msecs);
            }
        });
    }
    
    override void stopTimer()
    {
        _timerStop = true;
    }
}

void main()
{
    void clientMain()
    {
        auto client = clientTCP!(API)("localhost", 8030);
        client.progress ~= (int a) {writeln("Progress event: ", a);};
        client.timer ~= () {writeln("Timer event");};
        assert(client.request(42) == 42);
        assert(client.request("hello") == "hello");
        client.startTimer();
        client.stopTimer();
        client.closeTCP();
    }

    auto server = serveTCP!(APIServer, API)(8030);
    runTask(&clientMain);
    runEventLoop();
}
You can’t perform that action at this time.