معرفی gRPC و پیاده‌سازی آن در NET Core 3.1.

یکشنبه 24 اسفند 1399

gRPC یک سیستم فراخوانی منبع باز از راه دور است که در سال 2015 توسط گوگل توسعه یافته است.

معرفی gRPC و پیاده‌سازی آن در NET Core 3.1.

این سیستم از HTTP/2 برای انتقال پیام‌های باینری و بافرهای پروتکل پیش‌فرض به عنوان زبان تعریف رابط (IDL) برای توصیف رابط سرویس و ساختار پیام‌ها استفاده می‌کند.

    // The greeter service definition.  
     service Greeter {  
       // Sends a greeting  
       rpc SayHello (HelloRequest) returns (HelloReply) {}  
     }  
     // The request message containing the user's name.  
     message HelloRequest {  
       string name = 1;  
     }  
     // The response message containing the greetings  
     message HelloReply {  
       string message = 1;  
     }  

gRPC چهار نوع روش سرویس دهی را تعریف می‌کند:

1. Unary RPCs: در آن کلاینت تنها یک درخواست را به سرور ارسال می‌کند و پاسخ واحدی دریافت می‌کند.

2. Server streaming RPCs: کلاینت درخواست را به سرور ارسال می‌کند و جریانی (استریم) را برای خواندن دنباله‌ای از پیام‌ها دریافت می‌کند.

3. Client Streaming RPCs: کلاینت دنباله‌ای از پیام‌ها را می‌نویسد و آن‌ها را به سرور می‌فرستد، دوباره از یک جریان ارائه شده استفاده می‌کند.

4. Bidirectional Streaming RPCs: هر دو طرف دنباله‌ای از پیام‌ها را با استفاده از جریان خواندن-نوشتن ارسال می‌کنند.

اگر gRPC را با Web API مقایسه کنیم، تفاوت‌های زیر وجود دارد:

1. Web API مبتنی بر معماری REST است جایی که همانند gRPC مدل RPC را پیشنهاد می‌کند، مدلی که به عنوان کلاینت، ریموت پروسیجر را بر روی سرور فراخوانی می‌کند.

2. Web API از HTTP برای انتقال استفاده می‌کند در حالی که gRPC از HTTP/2 استفاده می‌کند.

3. داده های رد و بدل شده توسط Web API فرمت قابل خواندن توسط انسان است (معمولا JSON)، در حالی که gRPC از فرمت باینری به هم پیوسته استفاده می‌کند.

پیش نیازها

قبل از ایجاد سرویس‌های gRPC مطمئن شوید که NET Core 3.1 SDK. به صورت لوکال برای شما نصب شده است، این مورد می‌تواند با تایپ دستور زیر چک شود: ‘dotnet –version’ را در پنجره کنسول بررسی کنید. اگر نصب نشده است NET Core 3.1 (Linux, macOS, and Windows). را دانلود کرده و بر روی دستگاه خود نصب کنید.

ایجاد سرویس gRPC

برنامه‌ای که می‌خواهیم بسازیم یک میکروسرویس است که تخفیف را بر اساس نوع مشتری (gold یا platinum یا silver) محاسبه می‌کند که می‌تواند بیشتر قابل تعمیم باشد. با ساخت یک فولدر جدید، grpc-dotnet-microservice، و افزودن برنامه های کلاینت و سرویس شروع کنید.

به این فولدر بروید و پروژه سرویس را با نوشتن دستور زیر در پنجره کنسول بسازید:

دستور بالا یک نمونه جدید پروژه NET Core gRPC. در فولدر ساخته شده CalculateDiscountService می‌سازد.

تعریف قرارداد

اولین قدم تعریف قرارداد (contract) است که اینترفیسی است که عملکرد یا توابع نشان داده شده توسط سرویس را بیان می‌کند. در فریم‌ ورک gRPC این اینترفیس از طریق Protocol buffer یا protobuf تعریف می‌شود. به طور خاص این اینترفیس در فایل proto. تعریف شده است.

پس به فولدر ~\CalculateDiscountService\Protos بروید، فایل پیش فرض proto را به فایل discount-calculate-service.proto تغییر نام دهید و تغییرات زیر را انجام دهید:

syntax = "proto3";  
  
 option csharp_namespace = "CalculateDiscountService";  
 package CalculateDiscount;  
  
 service CalculateDiscountAmount {  
   rpc AmountCalculate (CalculateRequest) returns (CalculateReply);  
 }  
  
 message CalculateRequest {  
   string customertype = 1;  
 }  
  
 message CalculateReply {  
   double customerdiscount = 1;  
 } 

بیاید خط به خط بررسی کنیم. دو ردیف اول سینتکس ورژن proto buff را که در حال استفاده است و فضای نام سی شارپ را بیان می‌کند. خط بعدی نام پکیج را در این case = CalculateDiscount بیان می‌کند.

بلاک بعدی کد همانند کد زیر مشابه C# است:

class CalculateDiscountAmount {  
   public abstract CalculateReply AmountCalculate(CalculateRequest calculateRequest);  
}

در اینجا CalculateReply از نوع بازگشتی است، CalculateRequest پارامتر ورودی است، AmountCalculate یک تابع abstract است و CalculateDiscountAmount کلاس سی شارپ است. در فایل proto شماره منحصر به فرد پیام‌های CalculateRequest و CalculateReply در فیلدهای تعریف شده اختصاص داده شده‌اند. این وقتی که serialization و deserialization توسط protocol buffer انجام می‌شود ترتیب داده‌ها را مرتب می‌کند.

بعد از تعریف قرارداد، باید مطمئن شوید که برنامه از فایل جدید proto آگاه است. فایل CalculateDiscountService.csproj را همانند زیر آپدیت کنید:

<Project Sdk="Microsoft.NET.Sdk.Web">     
   <PropertyGroup>  
      <TargetFramework>netcoreapp3.1</TargetFramework>  
   </PropertyGroup>  
   <ItemGroup>  
      <Protobuf Include="Protos\discount-calculate-service.proto" GrpcServices="Server" />   </ItemGroup>  
   <ItemGroup>  
      <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />  
   </ItemGroup>  
</Project>

در اینجا نام فایل proto. همراه با اتربیوت GrpcServices که با ‘Server’ ست شده است تعیین شده است.

پیاده‌ سازی سرویس

به فولدر services بروید، فایل GreeterService.cs را به CalculateDiscountService.cs تغییر نام دهید و محتوای زیر را جایگزین کنید:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Threading.Tasks;  
using Grpc.Core;  
using Microsoft.Extensions.Logging;  
  
namespace CalculateDiscountService  
{  
    public class CalculateDiscountAmountService : CalculateDiscountAmount.CalculateDiscountAmountBase  
    {  
        private readonly ILogger<CalculateDiscountAmountService> _logger;  
        public CalculateDiscountAmountService(ILogger<CalculateDiscountAmountService> logger)  
        {  
            _logger = logger;  
        }  
  
        public override Task<CalculateReply> AmountCalculate(CalculateRequest request, ServerCallContext context)  
        {  
  
            return Task.FromResult(new CalculateReply  
            {  
                Customerdiscount=ReturnDiscount(request.Customertype)  
            });  
               
            
        }   
        private double ReturnDiscount(string customertype)  
        {  
            double discount=0.0;  
  
            if (customertype=="GOLD")  
            {  
                discount=15.6;   
            }  
            else if (customertype=="PLATINUM")  
            {  
                discount=20.6;  
            }  
            else if (customertype=="DIAMOND")  
            {  
                discount=25.6;  
            }  
  
            return discount;  
  
        }  
          
          
          
    }  
}

در اینجا ما کلاس CalculateDiscountAmountService که از کلاس CalculateDiscountAmount.CalculateDiscountAmountBase ارث‌ بری می‌کند را پیاده سازی می‌کنیم. این کلاس پایه از داده های موجود در فایل proto. (discount-calculate-service.proto) در زمان بیلد کردن تولید می‌شود.

این شامل تابع AmountCalculate است که پیاده سازی تعریف rpc در فایل proto. و انواع CalculateReply و CalculateRequest به عنوان نوع بازگشتی و پارامتر request که به عنوان نوع پیام تعریف شده است می‌باشد. همچنین فایل Startup.cs را برای مپ کردن کلاس CalculateDiscountAmountService به عنوان سرویس gRPC، همانند زیر آپدیت کنید:

اکنون به فولدر روت پروژه بروید، پروژه را با نوشتن دستورد ‘dotnet run’ در command prompt اجرا کنید.

با دستور بالا سرویس gRPC استارت می‌شود. اکنون برای تعامل با این سرویس ما یک برنامه کلاینت کنسول ایجاد خواهیم کرد.

ساخت gRPC Client

به فولدر \grpc-dotnet-microservice بروید و یک پروژه جدید با نوشتن دستور زیر در cmd بسازید:

دستور بالا یک برنامه کنسول را در فولدر DiscountCalculateClient ساخته شده می‌سازد. حالا به این فولدر می‌رویم و وابستگی‌های مورد نیاز را با نوشتن دستور زیر اضافه می‌کنیم:

dotnet add DiscountCalculateClient.csproj package Grpc.Net.Client  
dotnet add DiscountCalculateClient.csproj package Google.Protobuf  
dotnet add DiscountCalculateClient.csproj package Grpc.Tools

کتابخانه Grpc.Net.Client برای NET core client.، Google.Protobuf (کتابخانه زمان اجرای سی شارپ برای مدیریت بافرهای پروتکل و Grpc.Tools) کامپایلری که فایل‌های proto را به کد سی شارپ تبدیل می‌کند.

اکنون برنامه کلاینت باید از جزئیات مربوط به نحوه فراخوانی برنامه سرور، کدام پارامترها باید ارسال شوند و نوع بازگشتی احتمالی آگاه باشد.

این کار با افزودن فایل proto از قبل تعریف شده انجام می شود. ابتدا یک فولدر proto در DiscountCalculateClient بسازید و discount-calculate-service.proto را از سرویس gRPC کپی کرده و فایل DiscountCalculateClient.csproj project را با افزودن رفرنس فایل proto. آپدیت کنید.

<Project Sdk="Microsoft.NET.Sdk">  
  
  <PropertyGroup>  
    <OutputType>Exe</OutputType>  
    <TargetFramework>netcoreapp3.1</TargetFramework>  
  </PropertyGroup>  
  
  <ItemGroup>  
    <PackageReference Include="Google.Protobuf" Version="3.14.0" />  
    <PackageReference Include="Grpc.Net.Client" Version="2.33.1" />  
    <PackageReference Include="Grpc.Tools" Version="2.34.0">  
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>  
      <PrivateAssets>all</PrivateAssets>  
    </PackageReference>  
  </ItemGroup>  
    
  <ItemGroup>  
  <Protobuf Include="Protos\discount-calculate-service.proto" GrpcServices="Client" />  
  </ItemGroup>  
  
</Project>

توجه داشته باشید در اینجا المنت Protobuf اتربیوت GrpcServices را که با client ست شده است را دارد. اکنون برای فراخوانی سرویس gRPC از کلاینت، فایل Program.cs را ویرایش کنید.


    using System;  
    using CalculateDiscountService;  
    using Grpc.Net.Client;  
    using System.Net.Http;  
    namespace DiscountCalculateClient  
    {  
        class Program  
        {  
            static void Main(string[] args)  
            {  
                var httpHandler = new HttpClientHandler();  
      
                httpHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;  
      
                string customerType="GOLD";  
                var channel=GrpcChannel.ForAddress("https://localhost:5001",new GrpcChannelOptions { HttpHandler = httpHandler });  
                var client=new CalculateDiscountAmount.CalculateDiscountAmountClient(channel);  
                var request=new CalculateRequest{Customertype=customerType};  
                var reply=  client.AmountCalculate(request);  
      
                Console.WriteLine($"Discount for customer type {customerType}  is {( reply.Customerdiscount)}");  
                Console.WriteLine("Press any key to exit...");  
                Console.ReadKey();  
      
            }  
        }  
    }  

در اینجا ما یک کانال می‌سازیم که به آدرس جایی که سرویس در حال اجراست، همراه با افزودن پیکربندی مورد نیاز برای چشم پوشی از گواهی نامه (certificate) نامعتبر یا گواهی نامه‌ای که نصب نشده است و بعدا به عنوان کانستراکتور به کلاس gRPC client CalculateDiscountAmountClient ارسال می‌شود. در آخر تابع آن که با ارسال پارامتر required  فراخوانی می‌شود.

در زیر خروجی در برنامه کلاینت پس از راه‌اندازی از طریق دستور ‘dotnet run’ وجود دارد:

برخی از ویژگی‌های جدید ارائه شده در NET 5. برای gRPC عبارتند از:

1. بر روی مرورگر با gRPC-Web پشتیبانی می‌شود که باعث می‌‌شود با API مرورگر سازگار باشد.

2. می‌تواند با ورژن پشتیبانی شده ویندوز نصب شده، در HTTP.sys و IIS بر روی ویندوز هاست شود.

نتیجه گیری

در این مقاله ما در مورد gRPC، پیاده سازی آن در NET core 3.1. و ویژگی‌های جدید معرفی شده در NET 5. بحث کردیم.

برنامه نویسان

نویسنده 3224 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

تاکنون هیچ کاربری از این پست تشکر نکرده است

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید