
توی بخش اول یک سرور gRPC رو با پایتون بالا اوردیم و روی پورت 50051 بالا اوردیم که پروتکل ما به اسم helloworld.proto این بود
syntax = "proto3"; package helloworld; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply); } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
حالا میخوایم توی فلاتر متود SayHello رو صدا بزنیم و ریکوئست ما (یا همون آرگیومنت ورودی تابع ما) name خواهد بود و جواب (مقدار خروجی تابع ما) یک message هست.
اول از همه باید پروتوکل بافر یا همون protoc رو باید داشته باشیم که توی پارت اول گفتم و پکیج های مورد نیازمون رو اضافه میکنیم که پکیج ها grpc و protobuf هست که با دستور زیر اضافه میکنیم
flutter pub add grpc protobuf
پلاگین protobuf هم برای دارت نصب میکنیم با درستور زیر
dart pub global activate protoc_plugin
با استفاده از protoc که دانلود کردیم، فایل های دارت رو از روی فایل .proto خودمون که اسمش helloworld.proto هست با دستور زیر تولید می کنیم
protoc --dart_out=grpc:lib/src/generated -Iprotos protos/helloworld.proto
:dart_out=grpc-- یعنی هم messageها و هم کلاسهای gRPC تولید بشن.
خروجی میره تو lib/src/generated.
بعد از این، دو فایل ایجاد میشه:
helloworld.pb.dart (تعریف messageها)
helloworld.pbgrpc.dart (تعریف client/service)
حالا بعد از اجرای کد بالا کد های gRPC ما تولید شدن توی lib/src/generated
import 'package:grpc/grpc.dart'; import 'src/generated/helloworld.pb.dart'; import 'src/generated/helloworld.pbgrpc.dart'; Future<void> callSayHello(String name) async { final channel = ClientChannel( 'localhost', // ip address port: 50051, options: const ChannelOptions( credentials: ChannelCredentials.insecure(), // بدون TLS ), ); final stub = GreeterClient(channel); try { // Calling the sayHello method final response = await stub.sayHello( HelloRequest()..name = name, ); print('Server replied: ${response.message}'); } catch (e) { print('Caught error: $e'); } await channel.shutdown(); }
توی این کد اول از همه پکیج grpc رو ایمپورت می کردیم و اون فایل های تولید شده
یه تابع ساختم به نام callSayHello که آرگیومنت name به عنوان String میگیره که توی خط 19 جاگذاری کردم
توی این تابع یک چنل ساختم تا به سرور پایتون وصل بشیم'localhost' آدرس سرور هست (روی موبایل باید IP کامپیوترت رو بزنی).
port: 50051 همون پورتیه که در سرور پایتون باز کردیم.
ChannelOptions تنظیمات اتصال رو مشخص میکنه:
credentials: ChannelCredentials.insecure یعنی بدون رمزگذاری (TLS) وصل شو. چون سرور پایتون ما امن نشده.
این کانال مثل یک خط تلفن هست که همهی درخواستها از طریقش رد و بدل میشن.
خط 14 یک کلاینت از کلاس GreeterClient ساختم که توسط protoc و pbgrpc.dart تولید شده.
این کلاس همهی متدهای RPC (مثل sayHello) رو به شکل توابع Dart در اختیارمون میذاره.
stub یعنی واسطهای که از طریقش با سرور حرف میزنیم.
توی بلوک try میاد متود sayHello رو صدا میزنیم با آریگومنت name که با استفاده از ..(دونقطه) مقداری که از ورودی تابع callSayHello گرفتیم رو ست میکنیم
و در نهایت خط 26 کانال رو می بندیم تا ارتباط آزاد بشه و منابع شبکه اشغال نمونه
خب نتیجه میشه این
callSayHello("Adnan Kamali"); // اگر موفقیت آمیز بود Server replied: Hello, Adnan Kamali!
دوتا نکته:
1- اگر از موبایل برای تست استفاده میکنی یادت نره که دسترسی اینترنت رو توی AndroidManifest.xml بدی
2- اگر قراره که دیوایس های خارج از سرورت (کامپیوتر) تست بزنی حتما با ipconfig(توی ویندوز) ایپی ipv4 رو قرار بدی که فرمتش به شکل 192.168... بجای localhost هست
امیدوارم که این مطلب به درتون خورده باشه