چگونه یک سرور gRPC در Dart بسازیم؟

شکل ۱. gRPC
شکل ۱. gRPC
منتشر شده در blog.logrocket به تاریخ ۱۷ ژوئن ۲۰۲۱
لینک منبع How to build a gRPC server in Dart

در این آموزش، ما اصول gRPC، یک چارچوب RPC کارآمد، منبع باز و جهانی را بیان خواهیم کرد، کمی درباره زبان برنامه نویسی Dart مرور می‌کنیم و نحوه ساخت یک سرور gRPC در Dart را نشان می‌دهیم.‍

ما شما را به موارد زیر راهنمایی خواهیم کرد:

  • تکنولوژی gRPC چیست؟
  • چگونه بافرهای پروتکل کار می‌کنند
  • ساخت یک سرورgRPC درDart
  • نوشتن تعاریف خدمات
  • تدوین پروتو
  • ساخت سرویسgRPC
  • ساخت یک مشتریgRPC
  • تست سرور

تکنولوژی gRPC چیست؟

در اصل gRPC یک چارچوب ارتباطی بین پردازه (RPC) است که توسط گوگل ساخته‌شده و در سال ۲۰۱۵ منتشر شده‌است. منبع باز، زبان خنثی است و اندازه باینری فشرده‌ای دارد. gRPC همچنین از HTTP / ۲ پشتیبانی می‌کند و پلت‌فرم متقابل سازگار است.

تکنولوژی gRPC بسیار متفاوت از RPC معمولی است به این معنا که از بافررهای پروتکل به عنوانIDL خود برای تعریف رابط سرویس خود استفاده می‌کند. بافر پروتکل یک ابزار سری‌سازی ساخته‌شده توسط گوگل است که به شما اجازه می‌دهد تا ساختارهای داده‌ای خود را تعریف کنید، سپس از کامپایلر بافر پروتکل برای تولید کد منبع از این ساختارهای داده‌ای به زبان مورد نظر خود استفاده کنید. زبان تولید شده برای نوشتن و خواندن ساختارهای داده برای و از هر زمینه‌ای که می‌خواهیم استفاده می‌شود. مطابق اسناد رسمی، "بافرهای پروتکل مکانیزم قابل توسعه Google برای خنثی کردن زبان، خنثی از پلت‌فرم و قابل برنامه ریزی برای سریال سازی داده‌های ساخت یافته است - فکر کنید XML ، اما کوچک‌تر ، سریع‌تر و ساده‌تر است."

بافر پروتکل برای نوشتن رابط تعریف سرویس استفاده می‌شود، که برای تعریف ساختارها و روش‌های داده استفاده می‌شود. ساختار داده‌ها مانند انواع داده‌ها در زبان‌های تایپ‌شده آماری مانند جاوا است؛ آن‌ها به کامپایلر / مفسر می‌گویند که داده‌ها چگونه مورد استفاده قرار می‌گیرند. ساختارهای داده در رابط تعریف خدمات، انواع استدلالی هستند که به روش‌ها و انواع بازگشت روش‌ها منتقل می‌شوند. این رابط تعریف سرویس در یک فایل متنی با پسوند .proto نگهداری می‌شود. روش‌های موجود در رابط سرویس، روش‌هایی هستند که سرور gRPC در معرض آن‌ها قرار می‌گیرد تا توسط مشتریانgRPC فراخوانی شود.

تکنولوی gRPC سه جز دارد:

  • سرور میزبان پیاده‌سازی روش‌ها و گوش دادن به درخواست‌های مشتریان است
  • بافر پروتکل قالب پیام ساختار داده‌ها و روش‌ها از جمله آرگومان‌ها و نوع بازگشت آن‌ها را در اختیار دارد.
  • کلاینت روش‌های میزبانی شده توسط سرور را فراخوانی می‌کند. کلاینت درباره روش‌ها و انواع استدلال و بازگشت آن‌ها از رابط تعریف خدمات در فایل proto می‌داند.

با استفاده از این رابط سرویس، سرور gRPC کد سرور خود را تنظیم می‌کند که روش‌های موجود در رابط سرویس را اجرا می کند. خود را تنظیم می‌کند و برای درخواست‌ها (فراخوانی روش) از مشتریان گوش می‌دهد.

مشتری از رابط تعریف خدمات برای تولید نمونه مشتری استفاده می‌کند. این زیر مجموعه مشتری از جایی است که روش‌های موجود در سرور نامیده می‌شوند. یک برنامه مشتریgRPC می‌تواند درخواست‌های مستقیم به برنامه سرور بدهد. هم کلاینت و هم سرور از یک رابط مشترک استفاده می‌کنند، مانند یک قرارداد، که در آن تعیین می‌کند که هر یک از این عملیات‌ها چه روش‌ها، انواع و بازگشت‌هایی خواهند داشت.

چگونه بافرهای پروتکل کار می‌کنند

جذاب‌ترین چیز در مورد gRPC استفاده آن از بافر پروتکل است، که پروتکل را قادر می‌سازد تا platform-agnostics و polyglot باشد. این بدان معناست که سرور می‌تواند در یک زبان خاص نوشته شود و کلاینت به زبان دیگری توسعه یابد. بافر پروتکل این امکان را فراهم می‌کند زیرا کامپایلرهایی دارد که می‌توانند کد منبع زبان را از ساختار داده در تعاریف آن تولید کنند.

برای مثال، اجازه دهید بگوییم که سرور باید در JavaScript نوشته شود. ما برای تولید کد منبع جاوا اسکریپت از تعاریف موجود در پرونده .proto از کامپایلرproto استفاده خواهیم کرد. سپس سرور می‌تواند با استفاده از کد JavaScript به ساختارها و روش‌های داده دسترسی پیدا کرده و آن‌ها را دستکاری کند.

برای کلاینت، می‌خواهیم که در جاوا توسعه یابد، بنابراین کد منبع جاوا را از تعاریف تولید خواهیم کرد. سپس کلاینت می‌تواند روش‌ها را فراخوانی کند و با استفاده از کد جاوا به ساختار داده‌ها دسترسی پیدا کند. این همان چیزی است که منظور ما است وقتی می‌گوییم gRPC چند ضلعی و پلتفرم-اگنوستیک است.

توجه داشته باشید که بافرهای پروتکل تنها توسط gRPC استفاده نمی‌شوند. آن‌ها همچنین می‌توانند برای سری‌سازی به کار روند. معمولا از آن برای ارسال داده‌ها از طریق جریان‌ها استفاده می‌شود تا شما بتوانید ساختار داده خود را بدون هیچ گونه اتلاف سربار بخوانید و بنویسید.

ساخت یک سرور gRPC در Dart

حالا که اصول اولیه gRPC و بافرهای پروتکل را می‌دانیم، وقت آن است که سرورgRPC خود را در Dart بسازیم.

قبل از شروع، دقت کنید که Dart SDK را در دستگاه خود نصب کنید. برنامه اجراییDart باید در سطح جهانی در سیستم شما در دسترس باشد. فرمان زیر را برای بررسی اجرا کنید:

➜ grpc-dart dart --version

Dart SDK version: 2.10.5 (stable) (Tue Jan 19 13:05:37 2021 +0100) on "macos_x64"

ما همچنین به برخی از ابزارهای اولیه نیاز داریم. از آنجا که ما در حال توسعه سرورgRPC درDart هستیم، ما باید کامپایلر پروتو را برای Dart سازگار نصب کنیم. این کامپایلر کد منبعDart را از تعاریف خدمات در فایل .proto تولید می‌کند.

کامپایلر بافر پروتکل یک ابزار خط فرمان برای تدوین کد IDL در پروتو فایل‌ها و تولید کد منبع زبان مشخص برای آن است. برای دستورالعمل نصب، راهنمای gRPC را ببینید. دقت کنید که نسخه ۳ را دانلود کنید.

در نهایت افزونه Dart برای کامپایلر protoc کد منبع Dart را از کدIDL در فایل‌های .proto تولید می‌کند.

برای کاربران Mac، متصل‌شونده پروتکل Dart را با اجرای دستور زیر نصب کنید:

dart pub global activate protoc_plugin

این امر افزونه protoc_plugin را به طور کلی در دستگاه شما نصب می‌کند.

سپس، $PATH را به‌روزرسانی کنید تا protoc افزونه ما را ببیند:

export PATH=&quot$PATH:$HOME/.pub-cache/bin&quot

حالا وقت آن است که سرور را ایجاد کنید.

برای نمایش ما، ما یک سرور gRPC ایجاد خواهیم کرد که یک سرویس کتاب را مدیریت می‌کند. این سرویس روش‌هایی را نشان می‌دهد که برای آن‌ها استفاده خواهد شد:

  • همه کتاب‌ها را بردارید(GetAllBooks)
  • گرفتن یک کتاب از سرور از طریق شناسه آن (GetBook)
  • حذف یک کتاب(Deletebook)
  • ویرایش یک کتاب(EditBook)
  • ایجاد یک کتاب(CreateBook)

پروژهDart ما یک پروژه ساده و پیشانه خواهد بود. برای داربست کردن پروژه Dart فرمان زیر را اجرا کنید:

dart create --template=console-simple dart_grpc

دستور فرعی ایجاد شده به Dart اجرایی می‌گوید که ما می‌خواهیم یک پروژهDart ایجاد کنیم. --template=console-simple می‌گوید که ما می‌خواهیم پروژه Dart یک برنامه ساده کنسول باشد.

خروجی به شرح زیر خواهد بود:

Creating /Users/.../dart_grpc using template console-simple...
.gitignore
CHANGELOG.md
README.md
analysis_options.yaml
bin/dart_grpc.dart
pubspec.yaml
Running pub get...                     10.2s
Resolving dependencies...
Downloading pedantic 1.9.2...
Downloading meta 1.2.4...
Changed 2 dependencies!
Created project dart_grpc! In order to get started, type:
cd dart_grpc

پروژه ما در پوشه dart_grpc قرار خواهد گرفت.

فایلpubspec.yaml را باز کنید. این جایی است که ما میخ‌ها و وابستگی‌ها را بر روی یک برنامهDart تنظیم می‌کنیم. ما می‌خواهیم وابستگی‌های grpc و پروتوباف را نصب کنیم. خط زیر را در فایل pubspec.yaml اضافه کرده و ذخیره کنید:

dependencies:
grpc:
protobuf:

اکنون، pub را وارد کنسول خود کنید تا وابستگی‌ها نصب شوند.

نوشتن تعاریف خدمات

ما تعاریف سرویس خود را در یک پرونده .proto تعریف می کنیم. بنابراین بیایید یک فایلbook.proto ایجاد کنیم.

touch book.proto

کدProtobuf زیر را در پرونده book.proto اضافه کنید:

syntax = &quotproto3"
service BookMethods {
rpc CreateBook(Book) returns (Book);
rpc GetAllBooks(Empty) returns (Books);
rpc GetBook(BookId) returns (Book);
rpc DeleteBook(BookId) returns (Empty) {};
rpc EditBook(Book) returns (Book) {};
}
message Empty {}
message BookId {
int32 id = 1;
}
message Book {
int32 id = 1;
string title = 2;
}
message Books {
repeated Book books = 1;
}

این کد خیلی زیادی است. بیایید خط به خط آن را بررسی کنیم.

syntax = &quotproto3"

در اینجا، ما به کامپایلر بافر پروتکل می‌گوییم که از نسخه 3 زبان بافر پروتکل استفاده خواهیم کرد.

service BookMethods {
rpc CreateBook(Book) returns (Book);
rpc GetAllBooks(Empty) returns (Books);
rpc GetBook(BookId) returns (Book);
rpc DeleteBook(BookId) returns (Empty) {};
rpc EditBook(Book) returns (Book) {};
}

در اینجا، ما روش‌ها و خدماتی را که ارائه می‌دهند را اعلام می‌کنیم. کلمه کلیدی سرویس نشان‌دهنده یک سرویس واحد در یک gRPC است، بنابراین ما یک BookMethods سرویس ایجاد می‌کنیم. برای فراخوانی یک روش، این روش باید توسط خدمات آن ارجاع داده شود. این شبیه به کلاس و روش‌ها است؛ روش‌ها از طریق نمونه کلاس خود نامیده می‌شوند. ما می‌توانیم چندین سرویس تعریف‌شده در یک پروتو داشته باشیم.

روش‌ها درون هر سرویس توسط کلید واژه rpc نشان داده می‌شوند. RPC به کامپایلر می‌گوید که این روش یک نقطه پایانی rpc است و در معرض قرار می‌گیرد و از طریق از راه دور از مشتریان فراخوانی می‌شود. در تعریف ما، ما پنج روش در سرویس BookMethods داریم: CreateBook, GetAllBooks, GetBook, DeleteBook,EditBook.

  • سرویس CreateBook یک نوع داده کتاب را به عنوان arg در نظر می‌گیرد و یک نوع کتاب را برمی گرداند. اجرای این روش یک کتاب جدید ایجاد خواهد کرد.
  • سرویس GetAllBooks یک نوع خالی را به عنوانarg در نظر می‌گیرد و یک نوع کتاب را برمی گرداند. اجرای آن تمام کتاب‌ها را بر می‌گرداند
  • سرویس GetBook یک پارام ورودی از نوع BookId را می‌پذیرد و یک کتاب را برمی گرداند. اجرای آن یک کتاب خاص را بر می‌گرداند.
  • سرویس DeleteBook یک نوع BookId را به عنوان بخش ورودی در نظر می‌گیرد و یک نوع خالی را برمی گرداند. اجرای آن یک مدخل کتاب را از مجموعه حذف خواهد کرد
  • سرویس EditBook یک نوع کتاب را به عنوانarg در نظر می‌گیرد و یک نوع کتاب را برمی گرداند. اجرای آن کتاب را در این مجموعه تغییر خواهد داد

تمام داده‌های دیگر از این نقطه به پایین نشان‌دهنده داده‌ها یا انواع پیام‌ها هستند. ما داریم:

message Empty {}

واژه کلیدی پیام نشان‌دهنده انواع پیام است. هر نوع پیام دارای فیلد است و هر فیلد دارای عددی است که به طور منحصر به فرد آن را در نوع پیام شناسایی می‌کند.

تهی بودن نشان‌دهنده یک ساختار داده خالی است. این مورد زمانی استفاده می‌شود که می‌خواهیم هیچ استدلالی برای روش‌های rpc یا زمانی که روش‌ها هیچ ارزشی را بر نمی‌گردانند، ارسال نکنیم. این همان خلا در C / C + + است.

message BookId {
int32 id = 1;
}

این ساختار داده یک موضوع پیام ID کتاب را نشان می‌دهد. میدان id یک عدد صحیح را نگه می‌دارد که قبل از آن توسط کلید واژه int32 حرکت می‌کند. حوزه id شناسه یک کتاب را نگه می‌دارد.

message Book {
int32 id = 1;
string title = 2;
}

این ساختار داده نشان‌دهنده یک کتاب است. میدان شناسه دارای شناسه منحصر به فرد کتاب است و عنوان آن عنوان کتاب را در اختیار دارد. میدان عنوان رشته‌ای خواهد بود که کلید واژه رشته قبل از آن قرار دارد.

message Books {
repeated Book books = 1;
}

این نشان‌دهنده مجموعه‌ای از کتاب‌ها است. حوزه کتاب‌ها، آرایه‌ای از کتاب‌ها است. تکرار نشان‌دهنده زمینه‌ای است که یک لیست یا یک آرایه خواهد بود. کتاب قبل از نام فیلد نشان می‌دهد که این ردیف از انواع کتاب خواهد بود.

اکنون که ما نوشتن تعریف خدمات خود را انجام داده‌ایم، اجازه دهید فایل کتاب را گردآوری کنیم.

تدوین پروتو

ابزار پروتوک برای کامپایل فایل‌های .proto ما استفاده می‌شود. دقت کنید که این ابزار در سطح جهانی در سیستم شما موجود باشد:

protoc --version
libprotoc 3.15.8

این نسخه ابزار نمونه اولیه من در زمان نوشتن است. نسخه شما ممکن است متفاوت باشد، مهم نیست.

حالا اطمینان حاصل کنید که پایانه‌تان در پوشه اصلی دارت _ grpc باز شده‌است. اجرای فرمان زیر برای کامپایل پرونده book.proto:

protoc -I=. --dart_out=grpc:. book.proto

در اصل I=. پوشه منبعی را به کامپایلر می‌گوید که می خواهیم کدام قسمت اولیه را کامپایل کنیم.

زیرفرمان dart_out=grpc:.به کامپایلر protoc می‌گوید که ما در حال تولید کد منبع دارت از کتاب هستیم. تعاریف اولیه و استفاده از آن برای gRPC = grpc:. . به کامپایلر می‌گوید که فایل‌های دارت را در پوشه اصلی که ما از آن کار می‌کنیم بنویسد.

این فرمان پرونده‌های زیر را ایجاد خواهد کرد:

  • book.pb.dart
  • book.pbenum.dart
  • book.pbgrpc.dart
  • book.pbjson.dart

مهم‌ترین فایل، book.pb.dart است که حاوی کد منبع Dart برای ساختار داده‌های پیام در فایل book.proto است. همچنین شامل کلاس‌هایDart برای خالی بودن، BookId، کتاب و کتاب‌ها است. از اینها، نمونه‌های آن‌ها را ایجاد می‌کنیم و از آن‌ها در هنگام فراخوانی روش‌های rpc استفاده می‌کنیم.

فایل book.grpc.dart شامل کارگیر کلاس BookMethodClient است، که ما از آن برای ایجاد نمونه‌هایی برای فراخوانی روش‌های rpc و یک رابط BookMethodsServiceBase استفاده می‌کنیم. این رابط توسط سرور برای اضافه کردن پیاده‌سازی‌های روش‌ها اجرا خواهد شد.

سپس کد سرور خود را می‌نویسیم.

ساخت سرور gRPC

ما کد سرور gRPC خود را در فایل dart_grpc.dart می‌نویسیم. پرونده را باز کنید و کد زیر را پیست کنید:

import 'package:grpc/grpc.dart';

import 'package:grpc/src/server/call.dart';

import './../book.pb.dart';

import './../book.pbgrpc.dart';

class BookMethodsService extends BookMethodsServiceBase {

Books books = Books();

@override

Future<Book> createBook(ServiceCall call, Book request) async {

var book = Book();

book.title = request.title;

book.id = request.id;

books.books.add(book);

return book;

}

@override

Future<Books> getAllBooks(ServiceCall call, Empty request) async {

return books;

}

@override

Future<Book> getBook(ServiceCall call, BookId request) async {

var book = books.books.firstWhere((book) => book.id == request.id);

return book;

}

@override

Future<Empty> deleteBook(ServiceCall call, BookId request) async {

books.books.removeWhere((book) => book.id == request.id);

return Empty();

}

@override

Future<Book> editBook(ServiceCall call, Book request) async {

var book = books.books.firstWhere((book) => book.id == request.id);

book.title = request.title;

return book;

}

}

Future<void> main(List<String> args) async {

final server = Server(

[BookMethodsService()],

const <Interceptor>[],

CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]),

);

await server.serve(port: 50051);

print('Server listening on port ${server.port}...');

}

چه تکه رمزی! ترسناک به نظر می‌رسد، اما ساده‌تر از چیزی است که فکر می‌کنید.

بخش اول فایل‌های مورد نیاز را وارد می‌کند. ما کد grpc و کد grpc Dart را وارد کردیم. ما فایل‌هایbook.pb.dart وbook.pbgrpc.dart را وارد کردیم زیرا به کلاس‌های موجود در آن‌ها نیاز داریم.

در زیر، ما رابط BookMethodsServiceBase را در BookMethodsService توسعه می‌دهیم تا پیاده‌سازی‌ها را برای تمام سرویسBookMethods فراهم کنیم.

در کلاس BookMethodsService، ما تمام روش‌های ارائه پیاده‌سازی آن‌ها را مرور می‌کنیم. به دو پارامتر موجود در روش‌ها توجه کنید. اولین بخش، تماس ServiceCall ، حاوی اطلاعات متا در مورد درخواست است. بخش دوم حاوی اطلاعاتی است که ارسال می‌شود، که نوع داده‌هایی است که روش rpc به عنوان یک استدلال می‌پذیرد.

Books books = Books();

دستور بالا یک آرایه کتاب را تنظیم می‌کند.

در روش createBook، ما یک کتاب جدید ایجاد کردیم، شناسه، عنوان را تنظیم کردیم و آن را به آرایه کتاب‌ها در متغیر کتاب‌ها اضافه کردیم.

در روش getAllBooks، ما فقط متغیر کتاب را پس دادیم.

در روش getBook، ما شناسه را از شی درخواست BookId واکشی کردیم و از آن استفاده کردیم تا کتاب را از آرایه کتاب‌ها با استفاده از روشList # firstWhere دریافت کنیم و برگردانیم.

درdeleteBook ،bookID را از درخواست BookId خارج می‌کنیم و از آن به عنوان مکان نما برای حذف کتاب از آرایه کتاب‌ها با استفاده از روش List # removeWhere استفاده می‌کنیم.

در روش editBook ، درخواست arg حاوی اطلاعات کتاب است. ما کتاب را از مجموعه کتاب‌ها بازیابی کردیم و ارزش مالکیت عنوان آن را برای کسی که درخواستarg را ارسال کرده بود، ویرایش کردیم.

در نهایت، سرور را در تابع اصلی قرار می‌دهیم. ما مثال BookMethodsService را در یک آرایه به سازنده سرور منتقل کردیم. سپس روش سرویس را برای شروع سرور در پورت ۵۰۰۵۱ فراخوانی کردیم.

حال بیایید کلاینت را بسازیم.

ساخت gRPC کلاینت

یک پرونده client.dart در پوشه سطل ایجاد کنید:

touch bin/client.dart

آن را باز کرده و کد زیر را پیست کنید:

import 'package:grpc/grpc.dart';

import './../book.pb.dart';

import './../book.pbgrpc.dart';

class Client {

ClientChannel channel;

BookMethodsClient stub;

Future<void> main(List<String> args) async {

channel = ClientChannel('localhost',

port: 50051,

options: // No credentials in this example

const ChannelOptions(credentials: ChannelCredentials.insecure()));

stub = BookMethodsClient(channel,

options: CallOptions(timeout: Duration(seconds: 30)));

try {

//...

varbookToAdd1 = Book();

bookToAdd1.id = 1;

bookToAdd1.title = "Things Fall Apart";

varaddedBook1 = await stub.createBook(bookToAdd1);

print("Added a book: " +addedBook1.toString());

varbookToAdd2 = Book();

bookToAdd2.id = 2;

bookToAdd2.title = "No Longer at Ease";

varaddedBook2 = await stub.createBook(bookToAdd2);

print("Added a book: " +addedBook2.toString());

var allBooks = await stub.getAllBooks(Empty());

print(allBooks.books.toString());

var bookToDel = BookId();

bookToDel.id = 2;

await stub.deleteBook(bookToDel);

print("Deleted Book with ID: " + 2.toString());

var allBooks2 = await stub.getAllBooks(Empty());

print(allBooks2.books);

varbookToEdit = Book();

bookToEdit.id = 1;

bookToEdit.title = "Beware Soul Brother";

await stub.editBook(bookToEdit);

var bookToGet = BookId();

bookToGet.id = 1;

varbookGotten = await stub.getBook(bookToGet);

print("Book Id 1 gotten: " +bookGotten.toString());

} catch (e) {

print(e);

}

await channel.shutdown();

}

}

main() {

var client = Client();

client.main([]);

}

ما بسته‌های grpc.dart و پرونده‌های book.pb.dart و book.pbgrpc.dart را وارد کردیم. ما یک کلاس کلاینت کلاس ایجاد کردیم. ما یک استاب BookMethodsClient داریم؛ ایتاب نمونه BookMethodsClient را نگه می‌دارد، که جایی است که ما می‌توانیم روش‌های سرویس BookMethods را برای فراخوانی آن‌ها در سرور فراخوانی کنیم.

در روش اصلی، ما یک نمونه ClientChannel و همچنین یک نمونه BookMethodsClient پاس در نمونهClientChannel به سازنده آن ایجاد کردیم. BookMethodsClient از این نمونه برای پیکربندی استفاده می‌کند - به عنوان مثال، درگاهی که سرور gRPC در آن قرار دارد. در مورد ما، ۵۰۰۵۱ است و زمان وقفه است.

در داخل متن بیانیه try، ما روش های gPRC خود را فراخوانی کردیم. اول، ما یک کتاب با عنوان «چیزها سقوط می‌کنند» ایجاد کردیم و آن را به یک ID از ۱ اختصاص دادیم. ما متدcreateBook را در مقاله خرد فراخوانی کردیم و در کتاب نمونه bookToAdd1 به متدarg. با این کار روش createBook در سرور با شی addToAdd1 فراخوانی می‌شود.

سپس، ما یک نمونه کتاب جدید را با ID ۲ ایجاد کردیم، «نه بیشتر در Ease»، و روش createBook نامیده شد، که در نمونه کتاب عبور می‌کند. این از راه دور به روشcreateBook در سرور gRPC استناد کرد و یک کتاب جدید ایجاد شد.

ما از روش getAllBooks درخواست کردیم که تمام کتاب‌های سرور را تهیه کند.

بعد، ما یک شی BooKId راه اندازی کردیم، شناسه آن را روی 2 تنظیم کردیم. سپس، ما روش deleteBook را فراخوانی کردیم ،

پس از آن، ما روش BookId را فراخوانی کردیم، این کتاب را با شناسه 2("No Longer at Ease") از سرور پاک می‌کند.

توجه کنید که کجا یک کتاب را ویرایش می‌کنیم. ما یک نمونه از BookId با شناسه تنظیم شده در 1 و عنوان با عنوان "مراقب روح باش برادر" ایجاد کردیم. ما می‌خواهیم عنوان کتاب را با شناسه 1 ویرایش کنیم تا به جای "چیزها از هم بپاشند" بگوید "مراقب روح باش برادر". بنابراین ما با گذر از نمونهBookId ، روش editBook را فراخوانی کردیم.

در آخر، ما یک کتاب خاص را با استفاده از شناسه آن بازیابی کردیم. ما یک نمونهBookId را با شناسه تنظیم شده روی ۱ ایجاد کردیم. این بدان معنی است که ما می‌خواهیم کتاب را با شناسه ۱ به دست آوریم که نشان‌دهنده کتاب «مراقب روح باش برادر» است. بنابراین ما روش getBook را نام بردیم و مثال BookId را رد کردیم. بازگشت باید یک شی کتاب با عنوان « مراقب روح باش برادر» باشد.

بعد از همه این‌ها، کانال با فراخوانی روش خاموش کردن در ClientChannel از نمونه کانال خود، خاموش می‌شود.

تست سرور

اکنون زمان آن است که همه چیز را آزمایش کنیم.

➜ dart_grpc dart bin/dart_grpc.dart

Server listening on port 50051...

یک پایانه دیگر باز کنید و کلاینت را اجرا کنید:

➜ dart_grpc dart bin/client.dart

Added a book: id: 1

title: Things Fall Apart

Added a book: id: 2

title: No Longer at Ease

[id: 1

title: Things Fall Apart

, id: 2

title: No Longer at Ease

]

Deleted Book with ID: 2

[id: 1

title: Things Fall Apart

]

Book Id 1 gotten: id: 1

title: Beware Soul Brother

➜ dart_grpc

همین - سرور gRPC ما همانطور که در نظر گرفته شده کار می‌کند!

کد منبع کامل این مثال در GitHub موجود است.

نتیجه

ما چیزهای زیادی را در این برنامه آموزشی پوشش دادیم. ما با معرفی کلیgRPC و توضیح نحوه عملکرد آن از بافرهای پروتکل تا کلاینت شروع کردیم.

سپس چگونگی نصب ابزارها و پلاگین ها برای کامپایلر بافر پروتکل را نشان دادیم. اینها برای تولید کد منبع Dart از تعاریف پروتو استفاده می‌شوند. پس از آن، ما از فرآیند ایجاد یک سرویس GRPC واقعی در Dart، ساخت یک GRPC کلاینت، و فراخوانی روش‌های کلاینت عبور کردیم. پس از آن، ما از طریق فرآیند ایجاد یک سرویس gRPC واقعی در Dart، ساخت یک مشتری gRPC، و تماس دادن روش‌ها از سوی مشتری، به پیش رفتیم. gRPC بسیار قدرتمند است و چیزهای زیادی وجود دارد که شما می‌توانید با بازی کردن با آن به تنهایی کشف کنید. مثال‌های موجود در این آموزش باید پایه و اساس محکمی برای شما ایجاد کند.

این متن با استفاده از ربات ترجمه مقالات علم داده ترجمه شده و به صورت محدود مورد بازبینی انسانی قرار گرفته است.در نتیجه می‌تواند دارای برخی اشکالات ترجمه باشد.
مقالات لینک‌شده در این متن می‌توانند به صورت رایگان با استفاده از مقاله‌خوان ترجمیار به فارسی مطالعه شوند.