728x90
반응형

Server 구성

1. ASP.NET Core gRPC 서비스 프로젝트 생성


2. proto 파일 정의 (weather.proto)

syntax = "proto3";

import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "GrpcStreamServer";

package WeatherForecast;

// The weather service definition.
service WeatherForecasts {
  // Sends a weatherStream
 rpc GetWeatherStream (google.protobuf.Empty) returns (stream WeatherData);
}

message WeatherData {
  google.protobuf.Timestamp dateTimeStamp = 1;
  int32 temperatureC = 2;
  int32 temperatureF = 3;
  string summary = 4;
}


3. WeatherService.cs 에 동작 정의
(날짜별 온도값을 랜덤하게 반환한다.)

using Google.Protobuf.WellKnownTypes;

using Grpc.Core;

using GrpcStreamServer;

using static GrpcStreamServer.WeatherForecasts;

namespace GrpcStreamServer.Services
{
    public class WeatherService : WeatherForecastsBase
    {
        private readonly ILogger<WeatherService> _logger;

        public WeatherService(ILogger<WeatherService> logger) => _logger = logger;

        public override async Task GetWeatherStream(Empty _, IServerStreamWriter<WeatherData> responseStream, ServerCallContext context)
        {
            var rng = new Random();
            var now = DateTime.UtcNow;

            var i = 0;
            while (!context.CancellationToken.IsCancellationRequested && i < 20)
            {
                await Task.Delay(500); // Gotta look busy

                var forecast = new WeatherData
                {
                    DateTimeStamp = Timestamp.FromDateTime(now.AddDays(i++)),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = ""//Summaries[rng.Next(Summaries.Length)]
                };

                _logger.LogInformation("Sending WeatherData response");

                await responseStream.WriteAsync(forecast);
            }
        }
    }
}


4. Program.cs 에서 WeatherService Mapping

using GrpcStreamServer.Services;

var builder = WebApplication.CreateBuilder(args);

// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682

// Add services to the container.
builder.Services.AddGrpc();

var app = builder.Build();

app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.MapGrpcService<WeatherService>();
});

// Configure the HTTP request pipeline.
//app.MapGrpcService<WeatherService>();

app.Run();


5. Properties 의 launchSettings.json 파일에 서비스 주소 정의 및 기타 옵션 설정

{
  "profiles": {
    "GrpcStreamServer": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": false,
      "applicationUrl": "http://localhost:5038;https://localhost:7038",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}


6. appsettings.json 파일에서 Protocols 정의 및 Log Level 지정

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
}


7. appsettings.Development.json 파일에서 Develope 모드 일때 Info 도 로그가 찍히도록 Log Level 정의

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.Hosting": "Information",
      "Microsoft.AspNetCore.Routing.EndpointMiddleware": "Information"
    }
  }
}


8. Server 실행


Client 구성

1. 콘솔앱 프로젝트 생성


2. Server 에서 만들어진 proto 파일을 동일하게 Protos 폴더를 만들어 복사한다.


3. Nuget 설치
Google.Protobuf
Grpc.Net.Client
Grpc.Tools


4. 프로젝트파일 편집
<Protobuf Include="Protos\weather.proto" GrpcServices="Server" />
Server 를 Client 로 아래 처럼 바꾼다.
<Protobuf Include="Protos\weather.proto" GrpcServices="Client" />

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <None Remove="Protos\weather.proto" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Google.Protobuf" Version="3.20.1" />
    <PackageReference Include="Grpc.Net.Client" Version="2.45.0" />
    <PackageReference Include="Grpc.Tools" Version="2.45.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <Protobuf Include="Protos\weather.proto" GrpcServices="Client" />
  </ItemGroup>

</Project>


4.  빌드/다시빌드
빌드 하게되면 proto 파일을 이용해 c# 코드가 생성된다. (솔루션 탐색기에서 표시되지 않음)


5. 서버 연결 및 통신 (

using Google.Protobuf.WellKnownTypes;

using Grpc.Core;
using Grpc.Net.Client;

using GrpcStreamClient;

using var channel = GrpcChannel.ForAddress("http://localhost:5038");

var client = new WeatherForecasts.WeatherForecastsClient(channel);

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
using var streamingCall = client.GetWeatherStream(new Empty(), cancellationToken: cts.Token);

try
{
    await foreach (var weatherData in streamingCall.ResponseStream.ReadAllAsync(cancellationToken: cts.Token))
    {
        Console.WriteLine($"{weatherData.DateTimeStamp.ToDateTime():s} | {weatherData.Summary} | {weatherData.TemperatureC} C");
    }
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
{
    Console.WriteLine("Stream cancelled.");
}

https 로 연결하면 SSL 인증서를 요구한다.
GetWeatherStream 을 호출하면 서버에서 데이터를 실시간으로 전달해준다.
CancellationTokenSource 로 5초 지나면 호출을 Cancel 한다.

아래는 서버와 클라이언트간에 테스트 결과




소스 : https://github.com/kei-soft/GrpcSample

 

반응형

+ Recent posts