.proto
syntax = "proto3"; import "google/protobuf/timestamp.proto"; option csharp_namespace = "GrpcBidiStearming"; package greet; service Greeter { rpc SayHello (stream HelloRequest) returns (stream HelloReply); } message HelloRequest { string name = 1; google.protobuf.Timestamp timestamp = 2; } message HelloReply { string message = 1; google.protobuf.Timestamp timestamp = 2; }
Server
public override async Task SayHello(IAsyncStreamReader<HelloRequest> requestStream, IServerStreamWriter<HelloReply> responseStream, ServerCallContext context) { while (await requestStream.MoveNext() && !context.CancellationToken.IsCancellationRequested) { Console.WriteLine("Request : {0}, Timestamp : {1}", requestStream.Current.Name, requestStream.Current.Timestamp); await responseStream.WriteAsync(new HelloReply { Message = $"Hello {requestStream.Current.Name}", Timestamp = Timestamp.FromDateTime(DateTime.UtcNow) }); Console.WriteLine("Response : {0}, Timestamp : {1}", requestStream.Current.Name, requestStream.Current.Timestamp); } }
Client
static async Task Main(string[] args) { using var channel = GrpcChannel.ForAddress("http://localhost:5000"); var client = new Greeter.GreeterClient(channel); CancellationToken cancellationToken = new CancellationToken(false); var response = client.SayHello(new CallOptions(null, null, cancellationToken)); for (int i = 0; i < 100; i++) { var timestamp = Timestamp.FromDateTime(DateTime.UtcNow); await response.RequestStream.WriteAsync(new HelloRequest { Name = "Mahmood", Timestamp = timestamp }); Console.WriteLine(String.Format("Request : {0}", timestamp.ToString())); await response.ResponseStream.MoveNext(); Console.WriteLine(String.Format("Response : {0}, Timestamp : {1}", response.ResponseStream.Current.Message, response.ResponseStream.Current.Timestamp)); await Task.Delay(1000); } }
References
https://www.youtube.com/watch?v=wY4nMSUF9e0&list=PLUOequmGnXxPOlhyA57ijmEyOeVmYQt32&index=4