Jake Smokie
Jake Smokie

Reputation: 115

.NET Remoting TCPChannel analog for .NET Core

As .NET Remoting has been removed from .NET Core framework, I tried to use NetTcpBinding from the WCF library, but it's not included in .NET Core.

Is there some other analog of TCPChannel that I can use?

Upvotes: 3

Views: 5534

Answers (2)

Rainbird
Rainbird

Reputation: 61

If you have a large codebase that is based on .NET Remoting, then switching to WebAPI or gRPC could lead to rewrite half of your application.

CoreRemoting (MIT licensed) may be an alternative: https://github.com/theRainbird/CoreRemoting It makes is possible to migrate .NET Remoting based Client/Server applications to .NET Core / .NET 5. In contrast to gRPC or WebAPI, the procedure for CoreRemoting is very similar to .NET Remoting. Only remote method calls are made between .NET objects. A conversion of the calls to HTTP calls (building URLs with string concatenation) as with WebAPI is not necessary. Interfaces between client and server are defined in shared .NET assemblies instead of in a special interface language as with gRPC. Events and callbacks are supported out-of-the-box and can be used in a natural way for a C# developer (Compared to gRPC's more complex streaming approach).

The following example shows how a simple client/server chat application can be created using CoreRemoting.

Shared Contract Assembly

namespace HelloWorld.Shared
{
    public interface ISayHelloService
    {
        event Action<string, string> MessageReceived;
        
        void Say(string name, string message);
    }
}

Server

using System;
using CoreRemoting;
using CoreRemoting.DependencyInjection;
using HelloWorld.Shared;

namespace HelloWorld.Server
{
    public class SayHelloService : ISayHelloService
    {
        // Event to notify clients when users post new chat messages
        public event Action<string, string> MessageReceived;
        
        // Call via RPC to say something in the chat 
        public void Say(string name, string message)
        {
            MessageReceived?.Invoke(name, message);
        }
    }

    public static class HelloWorldServer
    {
        static void Main(string[] args)
        {
            using var server = new RemotingServer(new ServerConfig()
            {
                HostName = "localhost",
                NetworkPort = 9090,
                RegisterServicesAction = container =>
                {
                    // Make SayHelloSevice class available for RPC calls from clients
                    container.RegisterService<ISayHelloService, SayHelloService>(ServiceLifetime.Singleton);
                }
            });
            
            server.Start();
            
            Console.WriteLine("Server is running.");
            Console.ReadLine();
        }
    }
}

Client

using System;
using CoreRemoting;
using HelloWorld.Shared;

namespace HelloWorld.Client
{
    public static class HelloWorldClient
    {
        static void Main(string[] args)
        {
            using var client = new RemotingClient(new ClientConfig()
            {
                ServerHostName = "localhost",
                ServerPort = 9090
            });
            
            client.Connect();

            // Create a proxy of the remote service, which behaves almost like a regular local object
            var proxy = client.CreateProxy<ISayHelloService>();
            
            // Receive chat messages send by other remote users by event
            proxy.MessageReceived += (senderName, message) => 
                Console.WriteLine($"\n  {senderName} says: {message}\n");
            
            Console.WriteLine("What's your name?");
            var name = Console.ReadLine();

            Console.WriteLine("\nEntered chat. Type 'quit' to leave.");

            bool quit = false;

            while (!quit)
            {
                var text = Console.ReadLine();

                if (text != null && text.Equals("quit", StringComparison.InvariantCultureIgnoreCase))
                    quit = true;
                else
                {
                    // Post a new chat message
                    proxy.Say(name, text);
                }
            }
        }
    }
}

CoreRemoting is only working from .NET to .NET. If you need to communicate with Javascript, Java, Python, ..., then it is not the right tool. But if you only want to do RPC in a pure .NET environment and you want to do it in a comfortable way, thean CoreRemoting may be very helpful.

I would like to note that I am the developer of the CoreRemoting project.

Upvotes: 4

Jon Skeet
Jon Skeet

Reputation: 1499860

I would try to adopt a different RPC framework instead - ideally a platform-neutral one instead of one which is tightly coupled to .NET.

There are lots of options available. Just off the top of my head:

  • You could implement a Web API using ASP.NET Core, probably (but not necessarily) with a JSON payload.
  • You could use gRPC, probably (but not necessarily) using Protocol Buffers as the payload
  • You could use Thrift

Those are just examples - there are an awful lot of RPC and RPC-like frameworks available. None of these will be as "transparent" as using remoting, but:

  • They'll make it a lot clearer when you're making a network call
  • They'll allow you to evolve between service versions more easily
  • They'll allow you to use a mixture of platforms for servers and clients - which you may not need right now, but is good for future-proofing

Upvotes: 6

Related Questions