gRPC是一个高性能的开源RPC框架,最初由谷歌开发。本文主要介绍在.NET Core中想要使用WCF进程通信的替代方案,使用gRPC实现,可以以WCF样式创建服务。

1、gRPC简介

gRPC 是一个高性能、开源的远程过程调用(Remote Procedure Call,RPC)框架,它基于 HTTP/2 协议,支持跨平台开发。与 WCF 相比,gRPC 提供了更简洁的 API、更好的性能和更现代化的设计。gRPC 可以用于构建大型分布式系统,如谷歌的许多产品都在使用 gRP

该框架基于远程过程调用的客户机-服务器模型。客户机应用程序可以直接调用服务器应用程序上的方法,就像它是一个本地对象一样。

2、gRPC使用示例代码

1)服务端代码

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();
}
}

2)客户端代码

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();
}
}

3)客户机和服务器之间共享类

[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; }
}

4)服务描述符(descriptors)

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

5)序列化/反序列化(Serializer/Deserializer)

public static class Serializer<T>
{
public static byte[] ToBytes(T obj)
{
var buffer = new OutputBuffer();
var writer = new FastBinaryWriter<OutputBuffer>(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<T>.From(new FastBinaryReader<InputBuffer>(buffer));
return data;
}
}

官方文档https://github.com/grpc/grpc/tree/master/src/csharp

相关文档.NET Core 使用WCF的替代方案(IpcServiceFramework)

推荐文档