Bạn có thể sử dụng gRPC để lưu trữ các dịch vụ web bên trong ứng dụng lõi .NET.
Giới thiệu
- gRPC là một khung RPC mã nguồn mở, hiệu suất cao được phát triển ban đầu bởi Google.
- Khung công tác dựa trên mô hình máy khách-máy chủ của các cuộc gọi thủ tục từ xa. Ứng dụng khách có thể gọi trực tiếp các phương thức trên ứng dụng máy chủ như thể nó là một đối tượng cục bộ.
Thí dụ
Mã máy chủ
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();
}
}
Mã khách hàng
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();
}
}
Các lớp được chia sẻ giữa Máy khách và Máy chủ
[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; }
}
Bộ mô tả dịch vụ
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));
}
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;
}
}
Đầu ra
Đầu ra khách hàng mẫu
Đầu ra máy chủ mẫu
Người giới thiệu
- https://blogs.msdn.microsoft.com/dotnet/2018/12/04/annontic-net-core-3-preview-1-and-open-sourcing-windows-desktop-frameworks/
- https://grpc.io/docs/
- https://grpc.io/docs/quickstart/csharp.html
- https://github.com/grpc/grpc/tree/master/src/csharp
Điểm chuẩn
- http://csharptest.net/787/benchmarking-wcf-compared-to-rpclibrary/index.html
do I have to create a RESTful service?
- AFAIK có (hoặc sử dụng một số giải pháp của hãng thứ 3 tôi sẽ không biết bất kỳ cho NET Core)