Шаблон наблюдателя с использованием gRP C - C# - PullRequest
0 голосов
/ 04 мая 2020

Извините, если это глупый вопрос, но я не нахожу никакой полезной информации в inte rnet.

Кто-нибудь когда-либо пытался реализовать шаблон наблюдателя в C#, используя gRP * 1008? * как общение? Если да, пожалуйста, покажите мне ссылку.

Большое спасибо заранее и наилучшими пожеланиями.

1 Ответ

1 голос
/ 05 мая 2020

Я реализовал оболочку класса удобства клиента, чтобы превратить потоковые вызовы сервера в обычные события для проекта, над которым я работаю. Не уверен, что это то, что вы после. Вот простой сервер gRP C, который раз в секунду публикует время в виде строки.

syntax = "proto3";
package SimpleTime;

service SimpleTimeService
{
   rpc MonitorTime(EmptyRequest) returns (stream TimeResponse);
}

message EmptyRequest{}

message TimeResponse
{
   string time = 1;
}

Реализация сервера, которая просто зацикливается раз в секунду, возвращая строковое представление текущего времени до отмены , выглядит следующим образом

public override async Task MonitorTime(EmptyRequest request, IServerStreamWriter<TimeResponse> responseStream, ServerCallContext context)
{
   try
   {
      while (!context.CancellationToken.IsCancellationRequested)
      {
         var response = new TimeResponse
         {
            Time = DateTime.Now.ToString()
         };
         await responseStream.WriteAsync(response);
         await Task.Delay(1000);
      }
   }
   catch (Exception)
   { 
      Console.WriteLine("Exception on Server");
   }
}

Для клиента я создал класс, который содержит клиент gRP C и предоставляет результаты сервера, транслирующего вызов MonitorTime, как обычное событие ole. net.

   public class SimpleTimeEventClient
   {
      private SimpleTime.SimpleTimeService.SimpleTimeServiceClient mClient = null;
      private CancellationTokenSource mCancellationTokenSource = null;
      private Task mMonitorTask = null;
      public event EventHandler<string> OnTimeReceived;

      public SimpleTimeEventClient()
      {
         Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);
         mClient = new SimpleTime.SimpleTimeService.SimpleTimeServiceClient(channel);
      }

      public void Startup()
      {
         mCancellationTokenSource = new CancellationTokenSource();
         mMonitorTask = Task.Run(() => MonitorTimeServer(mCancellationTokenSource.Token));
      }

      public void Shutdown()
      {
         mCancellationTokenSource.Cancel();
         mMonitorTask.Wait(10000);
      }

      private async Task MonitorTimeServer(CancellationToken token)
      {
         try
         {
            using (var call = mClient.MonitorTime(new SimpleTime.EmptyRequest()))
            {
               while(await call.ResponseStream.MoveNext(token))
               {
                  var timeResult = call.ResponseStream.Current;
                  OnTimeReceived?.Invoke(this, timeResult.Time);
               }
            }
         }
         catch(Exception e)
         {
            Console.WriteLine($"Exception encountered in MonitorTimeServer:{e.Message}");
         }
      }
   }

Теперь создайте клиент и подпишитесь на событие.

  static void Main(string[] args)
  {
     SimpleTimeEventClient client = new SimpleTimeEventClient();
     client.OnTimeReceived += OnTimeReceivedEventHandler;
     client.Startup();
     Console.WriteLine("Press any key to exit");
     Console.ReadKey();
     client.Shutdown();

  }

  private static void OnTimeReceivedEventHandler(object sender, string e)
  {
     Console.WriteLine($"Time: {e}");
  }

, которое при запуске выдает

enter image description here

Я упустил много проверок на ошибки и тому подобное, чтобы сделать пример меньше. Одна вещь, которую я сделал, - это для интерфейсов gRP C со многими потоковыми вызовами сервера, которые могут или не могут представлять интерес для вызова клиентов, является реализация средства доступа к событиям (добавление, удаление), чтобы вызывать только потоковый метод на стороне сервера, если есть клиент, подписавшийся на завернутое событие Надеюсь, что это полезно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...