RpcLibrary

 

This library wraps PInvoke calls to the Win32 RPC APIs. This allows pure managed C# applications the ability to move byte arrays over the supported rpc protocols. The following is a basic demonstration:

void Test()
{
    //An id to identify the endpoint interface
    Guid iid = Guid.NewGuid();
    using (RpcServerApi server = new RpcServerApi(iid))
    {
        //Allow up to 5 connections over named pipes
        server.AddProtocol(RpcProtseq.ncacn_np, @"\pipe\testpipename", 5);
        //Authenticate via WinNT
        server.AddAuthentication(RpcAuthentication.RPC_C_AUTHN_WINNT);
        //Start receiving calls
        server.StartListening();
        //When a call comes, do the following:
        server.OnExecute +=
            delegate(IRpcClientInfo client, byte[] arg)
            {
                using (client.Impersonate())
                    return new byte[0];
            };

        //For the client, we specify the protocol, endpoint, and interface id to connect
        using (RpcClientApi client = new RpcClientApi(iid, RpcProtseq.ncacn_np, null, @"\pipe\testpipename"))
        {
            //Authenticate as ourselves
            client.AuthenticateAs(RpcClientApi.Self);
            //Call the server
            byte[] response = client.Execute(new byte[0]);
        }
    }
}

Protocols tested include named-pipes, LRPC, and TCP/IP. I’m sure you could get others working as well, but this was enough for a good start.

So someone might start asking “But why would you do this, why not use WCF, TCP Listener, Http Listener, etc?” I’ll try to address these, but you really need to have former experience with RPC to truely understand the benefits…

  • WCF and .Net Remoting are dog slow by comparison, up to 20 times slower.
  • WCF (IMHO) is poorly designed, have you seen anyone provide their own serialization or transport? Nope you havn’t. The original .Net Remoting layer did a much better job in the design; however, it did not provide an out-of-the-box transport layer that was even remotely acceptable.
  • Try it for yourself: A simple test of a WCF server and 10 client processes with 10 threads will fail horribly once the message complexity grows to a reasonable amount (around 100 FileInfo structures should suffice to blow it up).
  • WCF has it’s place, it’s easy, has a wider platform support, but it’s just not very good in reliability and it’s throughput and parallel processing capabilities are far from ideal.
  • Custom listeners (Tcp/NetPipe/Http) can also be useful; however, they simply cannot provide the robust channel that RPC will provide over the same protocols.

The next objection that seems obvious enough: your left with only a transport. There is no ability to serialize ‘messages’ from client to server and back. This is by choice, the transport provided here is intended to be only that, a transport. It moves bytes from one process to another, that is all it does. I’m currently working on final touches to a proto-buffer wrapper around this transport using Jon Skeet’s dotnet-protobufs. It’s fast, reliable, secure, and extensible… all the things I could only wish Microsoft had delivered in .Net 1.0.

Links
 

A few weeks ago I published NuGet packages for version 1.11.924.348.

 
I also managed to get protobuf-csharp-port on board. I absolutely live by protobuffers.

 
Finally I recently published a complete protobuf services rpc layer build on the RpcLibrary and protobuf-csharp-port. Of course much of the code there could be used with any raw transport like WCF, TCP, Named Pipes, etc so check it out. This library is also available on NuGet:

 
If you haven’t tried NuGet you should look at it. If you manage an open source library you really need to get published there. It has allowed me to publish projects that have dependencies without the need to check those dependencies into source control. This reduces the burden on source control, allows for smaller archives, and makes it easier to upgrade dependencies. So trash the binaries from your source control and get started with NuGet.

 

Just published the latest release v1.10.1124.358 of the C# Library hosted on google code. Major new functionality in the form of the new assembly CSharpTest.Net.RpcLibrary. This library wraps PInvoke calls to the Win32 RPC APIs. This allows pure managed C# applications the ability to move byte arrays over the supported rpc protocols. The following is a basic demonstration:

void Test()
{
    //An id to identify the endpoint interface
    Guid iid = Guid.NewGuid();
    using (RpcServerApi server = new RpcServerApi(iid))
    {
        //Allow up to 5 connections over named pipes
        server.AddProtocol(RpcProtseq.ncacn_np, @"\pipe\testpipename", 5);
        //Authenticate via WinNT
        server.AddAuthentication(RpcAuthentication.RPC_C_AUTHN_WINNT);
        //Start receiving calls
        server.StartListening();
        //When a call comes, do the following:
        server.OnExecute +=
            delegate(IRpcClientInfo client, byte[] arg)
            {
                using (client.Impersonate())
                    return new byte[0];
            };

        //For the client, we specify the protocol, endpoint, and interface id to connect
        using (RpcClientApi client = new RpcClientApi(iid, RpcProtseq.ncacn_np, null, @"\pipe\testpipename"))
        {
            //Authenticate as ourselves
            client.AuthenticateAs(RpcClientApi.Self);
            //Call the server
            byte[] response = client.Execute(new byte[0]);
        }
    }
}

Protocols tested include named-pipes, LRPC, and TCP/IP. I’m sure you could get others working as well, but this was enough for a good start.

So someone might start asking “But why would you do this, why not use WCF, TCP Listener, Http Listener, etc?” I’ll try to address these, but you really need to have former experience with RPC to truely understand the benefits…

  • WCF and .Net Remoting are dog slow by comparison, up to 20 times slower.
  • WCF (IMHO) is poorly designed, have you seen anyone provide their own serialization or transport? Nope you havn’t. The original .Net Remoting layer did a much better job in the design; however, it did not provide an out-of-the-box transport layer that was even remotely acceptable.
  • Try it for yourself: A simple test of a WCF server and 10 client processes with 10 threads will fail horribly once the message complexity grows to a reasonable amount (around 100 FileInfo structures should suffice to blow it up).
  • WCF has it’s place, it’s easy, has a wider platform support, but it’s just not very good in reliability and it’s throughput and parallel processing capabilities are far from ideal.
  • Custom listeners (Tcp/NetPipe/Http) can also be useful; however, they simply cannot provide the robust channel that RPC will provide over the same protocols.

 
The next objection that seems obvious enough: your left with only a transport. There is no ability to serialize ‘messages’ from client to server and back. This is by choice, the transport provided here is intended to be only that, a transport. It moves bytes from one process to another, that is all it does. I’m currently working on final touches to a proto-buffer wrapper around this transport using Jon Skeet’s dotnet-protobufs. It’s fast, reliable, secure, and extensible… all the things I could only wish Microsoft had delivered in .Net 1.0.

Anyway, enough ranting on the failings of Microsoft and .Net RPC. If your looking for a descent transport, LRPC support, or OOP C++ integration, this might be what your after.