در این مقاله می خواهیم به معرفی فریم ورک متن باز Remote Procedure Call (RPC)
بپردازیم، همانطور که از نام آن پیدا است این فریم ورک برای ارتباط بین دستگاهها، برنامههای کاربردی تلفن همراه و مرورگرها قابل اجرا است، در ادامه به شرح کامل آن می پردازیم.
معرفی gRPC
PRC
که مخفف Remote Procedure Call
می باشد، یک پروتکل برای فراخوانی یک سرویس از یک برنامه، داخل یک برنامه دیگر است. یعنی برنامه A
برای اینکه یه فانکشنی داخل برنامه B
رو بتونه فراخوانی کنه از این پروتکل استفاده میکنه، پس تا اینجا متوجه شدیم برای اینکه دوتا برنامه بخواهند بین همه دیگه دیتا ارسال و دریافت کنن از طریق این پروتکل میتوانند عمل کنن.
نکته
: این را همه در نظر داشته باشید این ارتباط در پروتکل TCP/IP
بر روی لایه Application
از طریق HTTP2
اطلاعات را ارسال و دریافت می کند.
یکی از مزیت های خوب دیگر فریم ورک این است که میتوانیم ارتباط بین چندین برنامه به زبان های مختلف را برقرار کنیم، به این معنی که مهم نیست مبداء یا مقصد هر دو با زبان PHP
نوشته شده باشند، پروتکل RPC
این امکان را می دهد که تمام برنامه های که می خواهند ارتباط با همدیگر برقرار کنند باید طبق استانداردی به نام proto
برای ارسال و دریافت داده ها عمل کنند.
همانطور که در تصویر بالا مشاهده می کنید یک سرویس که با زبان ++ C
نوشته شده است امکان ارتباط برقرار کردن بر روی gRPC server
فراهم کرده است که از طریق استانداری به نام proto
باهمدیگر ارتباط برقرار کرده اند، توجه داشته باشید که این ارتباط دارای یک Proto Request
و Proto Response
می باشد که تعیین می کنند که بین کلاینت و سرور چه دیتای ارسال و دریافت شود.
به صورت کلی ارتباط بین سرور و کلاینت ها به صورت RESTFull
می باشد که مرسوم ترین روش ارسال و دریافت اطلاعات است که از طریق پروتکل HTTP
بر روی بستر شبکه این کار را انجام می دهند. در ادامه می خواهیم تفاوت بین درخواست های RESTFull
, gRPC
را بررسی کنیم و همچنین در کنار آن فایل proto
را معرفی کنیم و اینکه gRPC
چگونه ارتباط و بین کلاینت ها برقرار می کند را شرح دهیم.
آشنایی و معرفی proto
همانطور که قبلا هم اشاره کردیم برای اینکه یک درخواست و پاسخ بین سرویس ها و کلاینت ها ارسال و دریافت بشه باید یک پروتکل یا استانداری را داشته باشید، برای همین منظور یک فایل در کنار پروژه شما وجود دارد، برای اینکه بهتر متوجه شوید مثالی که گفته می شود را هم خط به خط بررسی می کنیم، در اینجا سرویسی به نام support
(پشتیبانی) را داریم که امکان ارتباط برقرار کردن از طریق پروتکل RPC
در آن وجود دارد، ساختار فایل آن به شکل زیر می باشد :
syntax = "proto3";
package support;
service Ticket {
rpc CreateTicket (CreateTicketRequest) returns (TicketInfo) {}
}
message TicketInfo {
string id = 1;
CustomerInfo customer = 2;
UserInfo user = 3;
string subject = 4;
string content = 5;
string status = 6;
int32 priority = 7;
string created_at = 8;
repeated ReplyInfo replies = 9;
string payload = 10;
}
message CreateTicketRequest {
string subject = 1;
string content = 2;
int32 priority = 3;
CustomerInfo customer = 4;
UserInfo user = 5;
string payload = 6;
}
همانطور که در بالا مشاهده می کنید ساختار فایل gRPC
به این شکل است، ولی این دستورات چه کاری را انجام می دهند ؟! بیاین با یک مثال پیش بریم، در اینجا می خواهیم امکان ثبت یک تیکت و پاسخش را از طریق این فایل قرارداد کنیم.
ساختار فایل
در این بخش می خواهیم خط به خط کد را باهم بررسی کنیم و ببنیم چگونه یک استاندارد برای ارتباط RPC
تعریف می شود.
syntax = "proto3"
اولین چیزی که با آن مواجه می شوید این خط کد می باشد، در بحث ارتباط ها معمولا برای اینکه بروز رسانی های مختلفی انجام می شود ورژن های مختلف proto
با عدد جدا می شود، در این فایل ما از proto3
برای استاندارد ارسال و دریافت اطلاعات استفاده می کنیم، پس هر کلاینت دیگر بخواهد ارتباط برقرار کند باید آن هم قوانین را طبق استاندارد proto3
نوشته باشد.
package support
همانطور که اول هم گفتیم می خواهیم این ارتباط را برای سیستم پشتیبانی طراحی کنیم پس پکیجی که معرفی می کنیم به نام support
می باشد.
service Ticket
به صورت ساده بخواهم این بخش را توضیح دهم برای تمام حالت های که می خواهیم این ارتباط برقرار شود باید یک متد تعریف کنیم که ورودی و خروجی مشخصی دارد، پس درون سرویسی که برای Ticket
تعریف کرده ایم، به عنوان مثال می خواهیم عملیات ایجاد تیکت را از طریق RPC
مشخص کنیم.
rpc CreateTicket (CreateTicketRequest) returns (TicketInfo) {}
خط کد بالا به این معنی می باشد که یک ارتباط از نوع rpc
برای عملیات CreateTicket
می باشد که به عنوان ورودی CreateTicketRequest
را دریافت کرده و TicketInfo
را برمیگرداند.
پس تا اینجا ما توانستیم درون سرویس ایجاد شده یک عملیات را طبق استانداری که برایش تعیین کردیم مدیریت کنیم.
message TicketInfo
همانطور که در بخش متد داخل سرویس مشاهده کردین ورودی توابع و خروجی تابع مشخص شده بود، TicketInfo
دقیقا خروجی هست که قرار است از عملیات ایجاد تیکت برگشت داده شود، تمام پارامتر های داخل این آبجکت طبق مدل های دیتابیس معمولا تعریف می شود یا برحسب نیاز آن را قرارداد می کنیم. پارامتر ها بر حسب نوعی که دارن مشخص شده اند. فقط یک مورد را به عنوان نکته اینجا مطرح می کنم، داخل بدنه یک پارامتر به نام CustomerInfo customer = 2
وجود دارد، خود مقدار CustomerInfo
درونش یکسری پارامتر های مثل customer_key
وجود دارد، این نوع تعاریف دقیقا مثل ارتباطی است که بین موجودیت ها برقرار می شود، در اینجا می خواهیم بفهمیم که تیکت فرستاده شده توسط کدام کاربر(مشتری) می باشد پس اطلاعات خود مشتری میتواند یک آبجکت جدا باشد.
message TicketInfo {
string id = 1;
CustomerInfo customer = 2;
UserInfo user = 3;
string subject = 4;
string content = 5;
string status = 6;
int32 priority = 7;
string created_at = 8;
repeated ReplyInfo replies = 9;
string payload = 10;
}
message CreateTicketRequest
در اینجا هم ما پارامتر های ورودی برای ثبت یک تیکت جدید مشخص کرده ایم، توجه داشته باشید که messge
یک کلمه کلید می باشد و بعد آن نامی است که می خواهیم مشخص کنیم برای چه عملیات؟ چه دیتای؟ باید دریافت یا ارسال شود.
message CreateTicketRequest {
string subject = 1;
string content = 2;
int32 priority = 3;
CustomerInfo customer = 4;
UserInfo user = 5;
string payload = 6;
}
دقیقا تعریف ورودی های CreateTicketRequest
شبیه به TicketInfo
می باشد.
مقایسه RESTFull و gRPC
معمولا برای نوشتن api های که از سمت سرور می آید از معماری RESTFull
استفاده می شود که از طریق پروتکل HTTP
عملیات ارسال و دریافت اطلاعات انجام می شود در واقعا gRPC
هم خیلی به شبیه به آن می باشد که با این تفاوت که بر روی پروتکل HTTP2
دیتا را ارسال و دریافت می کند و هم ایمن تر و سریع تر می باشد، در ادامه یکسری از مزیت های آن را مطرح می کنیم .
این پروتکل برای ارسال و دریافت اطلاعات به صورت پیش فرض برای سریالایز کردن اطلاعات از ProtocolBuffer
استفاده می کنه که توسط گوگل نوشته شده.
فرمت اطلاعاتی که داخل ProtocolBuffer
هست به صورت باینری می باشد، به معنی که حجم اطلاعات کاهش پیدا می کند به این معنی که اطلاعات قبل از ارسال فشرده میشن و حجم کمتری از ترافیک شبکه را اشغال میکنن.
یکی از خوبی های دیگ gRPC
اینکه که schema
تعریف شده در سمت سرور توابع ورودی و خروجی را برای کلاینت مشخص می کند. با این کار میتونیم بفهمیم چه متدهای با چه ورودی و خروجی در سمت سرور وجود دارد.
قابلیت خوب دیگ اینکه Bi-directional Streaming
برای جریانی از داده ها استفاده میکنه، به این معنی که ارسال و دریافت اطلاعات به صورت همه زمان صورت می گیرد پس برای کار با داده های مثل فیلم بسیار مناسب است.
اخرین مورد که قبلا هم اشاره کردیم اینکه بر روی پروتکل HTTP2
ارسال و دریافت اطلاعات انجام میدهد که خیلی امن و سریع می باشد.
در نهایت این فریم ورک توسط گوگل نوشته شده است و توسط شرکت های بسیار مطرح که در پایین اشاره می شود مورد استفاده قرار گرفته است.
اگر نیاز به تست درخواست های RPC
خود داشتید میتوانید نرم افزار BloomRPC را نصب کنید.
توجه داشته باشید که تمام قطع کدهای که در این مقاله اورده شد در فایلی به نام support.proto
قرار گرفته است، امیدوارم این مقاله برایتان مفید باشد.