Remote procedure call là gì

  -  

Remote Procedure Call

Trong Khi thiết kế ứng dụng, bao hàm áp dụng được sản xuất thành nhiều các bước khác biệt, chạy đồng thời. Các quá trình này hoàn toàn có thể chuyển động bên trên và một khối hệ thống, hoặc chuyển động trên những khối hệ thống không giống nhau. Các quá trình này thương lượng dữ liệu qua lại với nhau, quy trình này Call là Interprocess Communications (IPC). Remote Procedure Gọi (RPC) là 1 trong cách thức dùng làm dàn xếp tài liệu. RPC để cho bài toán tiến hành IPC thuận lợi, giống như một lời hotline hàm thông thường. RPC rất có thể được triển khai giữa nhì tiến triền bên trên và một máy vi tính, hoặc thân các máy vi tính không giống nhau vào mạng.

Bạn đang xem: Remote procedure call là gì

Microsoft Windows API hỗ trợ nguyên tắc RPC tuân thủ theo đúng Open Software Foundation (OSF) Distributed Computing Environment (DCE). Có nghĩa là, bất kỳ áp dụng nào sử dụng RPC nhờ vào Windows API, trọn vẹn có thể Bàn bạc với ứng dụng không giống sử dụng RPC theo chuẩn DCE.

Thuật ngữ:

interface: Giao diện biểu hiện phương pháp giao tiếp của RPC. RPC thực hiện một ngôn từ đặc biệt để thể hiện interface, chính là Interface Definition Language (IDL). IDL của Microsoft là Microsoft Interface Definition Language (MIDL).Remote Procedure : là các hàm được xuất bản tuân thủ theo đúng interface tư tưởng trước.Client: là chương trình thực hiện RPC nhằm thực hiện một trách nhiệm.Server là lịch trình dấn những tận hưởng từ client, tiến hành trọng trách định trước, trả lời công dụng cho client.

Các yếu tố chủ yếu của Microsoft RPC:

Trình biên dịch MIDL (MIDL compiler)Các thỏng viện links cồn (Rpcrt4.dll)Name service providerEndpoint mapper

Microsoft Interface Definition Language (MIDL)

Đây là ngữ điệu diễn tả interface được Microsoft sử dụng. Viết một tệp tin IDL cũng tương tự nhỏng khi tư tưởng header vào ngôn ngữ C, nhưng mà bản thân ngôn ngữ này còn có thêm một vài ba từ khoá khác biệt. IDL tập trung miêu tả nằm trong tính của hàm và các ttê mê số của hàm. Sau khi biểu lộ IDL dứt, nó cần phải dịch thành những tệp tin .c với .h thông qua MIDL compiler.

Để dễ nắm bắt, tôi vẫn bước đầu bằng một ví dụ:

#include #include #define MAX_BUFF (256)void SayYouDo( __in const char *s) printf("%s", s);void main(void) char buf; printf("Enter a string and press . Enter QUIT to lớn exit. "); bởi memset(buf, 0, sizeof(buf)); if (fgets(buf, 256, stdin)== NULL) break; SayYouDo(buf); while (strcmp(buf, "QUIT "));Logic của công tác này cực kỳ 1-1 giản:

Đợi người tiêu dùng nhập dữ liệu, hiển thị nó ra screen.Nếu người tiêu dùng nhập QUIT, thì hiển thị QUIT với thoát.

Câu hỏi đề ra là giả dụ viết lại lịch trình này, chũm lời điện thoại tư vấn hàm SayYouDo() thành RPC thì đã chũm nào?

Xây dựng tệp tin IDL

// File SayYouDo.idl// Compiling SayYouDo.idl: // midl /app_config SayYouDo.idl< // interface unique identifier. uuid(B0ACC031-03B0-45de-8751-D205210BA42D), // Version 1.0 of this interface. version(1.0), // This interface will use an implicit binding implicit_handle(handle_t hBinding)>interface RpcExample void SayYouDo( const char* s // a zero-terminated string. ); void ShutdownRpc( void );Mô tả bên trên bao gồm:UUID: Các interface được phân biệt với nhau thông qua uuid. Giá trị này phải là nhất. UUID rất có thể hình thành bằng nguyên tắc Create UUID của Microsoft. Công vắt này còn có sẵn trong bộ Visual Studio.

*

version: cho biết phiên bạn dạng của interface. Trong ví dụ này là một.0

binding handle:

Để đọc khái niệm này, buộc phải phát âm Binding là một quá trình thiết lập một liên kết logic (logical connection) thân chương trình client cùng chương trình server. Thông tin về kết nối nữa client cùng server được biểu diễn thông qua 1 kết cấu, gọi là binding handle.

Trên thực tế, RPC client và RPC VPS rất có thể nằm ở cùng một máy tính hoặc trên 2 máy tính xách tay không giống nhau. Client với hệ thống hoàn toàn có thể tiếp xúc thông qua các một số loại giao thức khác nhau (TCPhường, Named pipe, ...). Về mặt lô ghích, client cùng VPS chỉ đọc là vẫn liên kết với nhau trải qua binding handle nhưng mà không bắt buộc gọi nền tảng gốc rễ tiếp xúc dưới (TCP., Named pipe, ...) vẫn cần sử dụng là gì. Tsay đắm khảo list những Protocol rất có thể cần sử dụng được: Protocol Sequence.

Có 3 một số loại binding handle có thể cần sử dụng được, gồm những: implicit_handle, auto_handle explicit_handle.

implicit_handle có nghĩa là binding handle được phát âm ngầm định, không cần thiết phải gồm vào tđam mê số Lúc gọi hàm RPC. Nên cần sử dụng loại này.explicit_handle tức là binding handle được phát âm tường minch, bắt buộc có trong tđắm đuối số khi điện thoại tư vấn hàm RPC. Đây là tmê man số thứ nhất của hàm.

Xem thêm: Top 10 Các Trang Đào Bitcoin Free Hàng Ngày Không Cần Máy Đào

auto_handle: rất có thể phát âm là loại phối hợp của 2 thứ hạng bên trên.

Biên dịch MIDL bằng MIDL compiler tất cả sẵn của Visual Studio

tùy chọn /app_config cho phép áp dụng một trong những từ khóa của Application Configuration File (ACF) bên phía trong tệp tin IDL.

interface: Định nghĩa interface bao hàm thương hiệu hàm với các tđam mê số. Các tsay đắm số đề nghị có mang rõ loại tài liệu . Thuộc tính của các trường tài liệu vào ngôn ngữ IDL hoàn toàn có thể xem thêm ngơi nghỉ đây: IDL Attributes

Compile MIDL file

Sử dụng MIDL Compiler để sinch code mang đến client và VPS. Quá trình này sẽ tạo nên ra 3 file:

SayYouDo.h: Header cho cả client với server

SayYouDo_c.c: Client stub

SayYouDo_s.c: hệ thống stub

Trong quá trình biên dịch, nên lưu ý: lựa chọn đúng nền tảng gốc rễ (x86, x64 xuất xắc ia64) Lúc biên dịch. Tmê mẩn số này hoàn toàn có thể tham khảo thông qua tùy chọn /win32, /x64 hoặc /ia64 của midl compiler.

*

RPC Server

#include #include "../Protocol/SayYouDo.h"#pragma comment(lib, "Rpcrt4.lib") // RPC Functions#if defined UNICODE || defined _UNICODE#define RPC_TSTR RPC_WSTR#else#define RPC_TSTR RPC_CSTR#endif#define RPC_PROTOCOL TEXT("ncacn_np")#define RPC_NETWORK_ADDRESS (NULL)#define RPC_END_POINT TEXT("pipehello")HANDLE hStopEvent = NULL;// Server functions.#ifdef __cplusplusextern "C"{#endifvoid SayYouDo(const unsigned char *s){std::cout (RPC_PROTOCOL), // protocol.RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Backlog queue .reinterpret_cast(RPC_END_POINT), // endpoint.NULL); // No security.if (status)exit(status);std::cout

Đăng kí interface

Chương thơm trình vẫn đăng kí một interface cùng với hệ thống thông qua hàm RpcServerRegisterIf2.

RPC_STATUS RPC_ENTRY RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv, unsigned int Flags, unsigned int MaxCalls, unsigned int MaxRpcSize, RPC_IF_CALLBACK_FN *IfCallbackFn);

Theo tay nghề phiên bản thân, chúng ta đề nghị sử dụng hàm RpcServerRegisterIf2 hoặc RpcServerRegisterIfEx ráng mang đến RpcServerRegisterIf Khi đăng kí interface. Nên thiết lập cấu hình cờ RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH Lúc đăng kí interface, IfCallbackFn thì rất có thể thiết lập cấu hình hoặc đặt bằng NULL.

Điều này đã tách mang đến client ( xin kể lại là client) bị crash giữa chừng Lúc liên kết cho tới RPC server. Lỗi này khá khó khăn chịu! Client có khả năng sẽ bị crash Lúc Điện thoại tư vấn hàm NdrClientCall2, trong những lúc rứa kết nối cho tới hệ thống. Các bạn sẽ không lúc nào cần sử dụng hàm NdrClientCall2 vào code của các bạn, NdrClientCall2 được hiện ra tự động hóa vào client code stub.

RpcServerListen nhằm bắt đàu dấn kết nối từ client. Sau hàm này, hệ thống có thể xem như là sẵn sàng.

Implement interface

tại chỗ này, bản thân implement mang đến 2 hàm SayYouDo với ShutdownRpc.

Phía hệ thống cần implement 2 hàm cho cai quản cỗ nhớ:Hai hàm này được sử dụng khi khối hệ thống cấp phát bộ nhớ đụng lúc chạy.

void* __RPC_USER midl_user_allocate(size_t size);void __RPC_USER midl_user_free(void* p);

Shutting down the server

Để tắt RPC hệ thống, các bạn cần sử dụng hàm RpcMgmtStopServerListening. Để biết khi nào tắt server, thì hoàn toàn có thể điều khiển qua client nhỏng mình làm.

RPC Client

#include #include #include "../Protocol/SayYouDo.h"#pragma comment(lib, "Rpcrt4.lib") // RPC Functions#if defined UNICODE || defined _UNICODE#define RPC_TSTR RPC_WSTR#else#define RPC_TSTR RPC_CSTR#endif#define RPC_PROTOCOL TEXT("ncacn_np")#define RPC_NETWORK_ADDRESS (NULL)#define RPC_END_POINT TEXT("pipehello")int main( int argc, char *argv<>){RPC_STATUS status;RPC_TSTR szStringBinding = NULL;// Creates a string binding handle.status = RpcStringBindingCompose(NULL, // UUID to lớn bind khổng lồ.reinterpret_cast(RPC_PROTOCOL), // protocol.reinterpret_cast(RPC_NETWORK_ADDRESS), // network address to use.reinterpret_cast(RPC_END_POINT), // endpoint.NULL, // Protocol dependent network options to use.&szStringBinding); // String binding output.if (status)exit(status);// Validates the format of the string binding handle status = RpcBindingFromStringBinding(szStringBinding, // The string binding to lớn validate.&hBinding); // Put the result in the implicit binding handleif (status)exit(status);char buf<256>;memset(buf, 0, sizeof(buf));bool bStopped = false;std::cout Client thực hiện RpcStringBindingCompose để chế tạo ra binding string với chuyển đổi string thành binding handle thông qua hàm RpcBindingFromStringBinding

Client cũng cần phải 2 hàm mang lại Việc cai quản bộ nhớ lưu trữ động, như sinh hoạt hệ thống.

Xem thêm: Phân Biệt Ý Nghĩa Của Revenue, Income Và Sales Revenue Là Gì ?

Sau Khi tạo handle thành công xuất sắc, client sẽ điện thoại tư vấn hàm trải qua RPC nhỏng sau:

RpcTryExcept SayYouDo((const unsigned char *)buf); RpcExcept(1) { std::cerr

Compile & Link

*

*

Lưu ý khi dùng explicit_handle

Trong ngôi trường phù hợp cần sử dụng explicit_handle thì nên knhị báo nlỗi sau:

// File SayYouDo.idl// Compiling SayYouDo.idl: // midl /app_config SayYouDo.idl< // interface unique identifier. uuid(B0ACC031-03B0-45de-8751-D205210BA42D), // Version 1.0 of this interface. version(1.0), explicit_handle>interface RpcExample void SayYouDo( handle_t hBinding, const char* s // a zero-terminated string. ); void ShutdownRpc( handle_t hBinding );Server :

// Server functions.#ifdef __cplusplusextern "C"{#endifvoid SayYouDo(handle_t hBinding, const unsigned char *s){std::cout Client

// Validates the format of the string binding handle status = RpcBindingFromStringBinding( szStringBinding, // The string binding khổng lồ validate. &hBinding); // Put the result in the implicit binding handle if (status) exit(status); RpcTryExcept SayYouDo(hBinding, (const unsigned char *)buf); RpcExcept(1) { std::cerr

Source Code - Mã nguồn

Đây là toàn cục mã mối cung cấp lịch trình mẫu: RpcExample.