What replaces WCF in .Net Core?

后端 未结 9 537
逝去的感伤
逝去的感伤 2020-11-30 19:27

I am used to creating a .Net Framework console application and exposing a Add(int x, int y) function via a WCF service from scratch with Class Library (.Net Fra

9条回答
  •  鱼传尺愫
    2020-11-30 19:30

    You can use gRPC for hosting web services inside .NET core application.

    Introduction

    1. gRPC is a high performance, open source RPC framework initially developed by Google.
    2. The framework is based on a client-server model of remote procedure calls. A client application can directly call methods on a server application as if it was a local object.

    Example

    Server Code

    class Program
    {
        static void Main(string[] args)
        {
            RunAsync().Wait();
        }
    
        private static async Task RunAsync()
        {
            var server = new Grpc.Core.Server
            {
                Ports = { { "127.0.0.1", 5000, ServerCredentials.Insecure } },
                Services =
                {
                    ServerServiceDefinition.CreateBuilder()
                        .AddMethod(Descriptors.Method, async (requestStream, responseStream, context) =>
                        {
                            await requestStream.ForEachAsync(async additionRequest =>
                            {
                                Console.WriteLine($"Recieved addition request, number1 = {additionRequest.X} --- number2 = {additionRequest.Y}");
                                await responseStream.WriteAsync(new AdditionResponse {Output = additionRequest.X + additionRequest.Y});
                            });
                        })
                        .Build()
                }
            };
    
            server.Start();
    
            Console.WriteLine($"Server started under [127.0.0.1:5000]. Press Enter to stop it...");
            Console.ReadLine();
    
            await server.ShutdownAsync();
        }
    }
    

    Client Code

    class Program
    {
        static void Main(string[] args)
        {
            RunAsync().Wait();
        }
    
        private static async Task RunAsync()
        {
            var channel = new Channel("127.0.0.1", 5000, ChannelCredentials.Insecure);
            var invoker = new DefaultCallInvoker(channel);
            using (var call = invoker.AsyncDuplexStreamingCall(Descriptors.Method, null, new CallOptions{}))
            {
                var responseCompleted = call.ResponseStream
                    .ForEachAsync(async response => 
                    {
                        Console.WriteLine($"Output: {response.Output}");
                    });
    
                await call.RequestStream.WriteAsync(new AdditionRequest { X = 1, Y = 2});
                Console.ReadLine();
    
                await call.RequestStream.CompleteAsync();
                await responseCompleted;
            }
    
            Console.WriteLine("Press enter to stop...");
            Console.ReadLine();
    
            await channel.ShutdownAsync();
        }
    }
    

    Shared Classes between Client and Server

    [Schema]
    public class AdditionRequest
    {
        [Id(0)]
        public int X { get; set; }
        [Id(1)]
        public int Y { get; set; }
    }
    
    [Schema]
    public class AdditionResponse
    {
        [Id(0)]
        public int Output { get; set; }
    }
    

    Service descriptors

    using Grpc.Core;
    public class Descriptors
    {
        public static Method Method =
                new Method(
                    type: MethodType.DuplexStreaming,
                    serviceName: "AdditonService",
                    name: "AdditionMethod",
                    requestMarshaller: Marshallers.Create(
                        serializer: Serializer.ToBytes,
                        deserializer: Serializer.FromBytes),
                    responseMarshaller: Marshallers.Create(
                        serializer: Serializer.ToBytes,
                        deserializer: Serializer.FromBytes));
    }
    

    Serializer/Deserializer

    public static class Serializer
    {
        public static byte[] ToBytes(T obj)
        {
            var buffer = new OutputBuffer();
            var writer = new FastBinaryWriter(buffer);
            Serialize.To(writer, obj);
            var output = new byte[buffer.Data.Count];
            Array.Copy(buffer.Data.Array, 0, output, 0, (int)buffer.Position);
            return output;
        }
    
        public static T FromBytes(byte[] bytes)
        {
            var buffer = new InputBuffer(bytes);
            var data = Deserialize.From(new FastBinaryReader(buffer));
            return data;
        }
    }
    

    Output

    Sample client output

    Sample Server output

    References

    1. https://blogs.msdn.microsoft.com/dotnet/2018/12/04/announcing-net-core-3-preview-1-and-open-sourcing-windows-desktop-frameworks/
    2. https://grpc.io/docs/
    3. https://grpc.io/docs/quickstart/csharp.html
    4. https://github.com/grpc/grpc/tree/master/src/csharp

    Benchmarks

    1. http://csharptest.net/787/benchmarking-wcf-compared-to-rpclibrary/index.html

提交回复
热议问题