Rpc là gì? các thức hoạt động của rpc

Remote Procedure Call

Trong Khi lập trình vận dụng, có những ứng dụng được tạo ra thành nhiều quá trình không giống nhau, chạy đôi khi. Các quá trình này có thể chuyển động trên và một khối hệ thống, hoặc hoạt động bên trên những khối hệ thống không giống nhau. Các tiến trình này trao đổi tài liệu qua lại cùng nhau, quy trình này Call là Interprocess Communications (IPC). Remote Procedure Gọi (RPC) là 1 phương thức dùng để làm Bàn bạc tài liệu. RPC để cho vấn đề tiến hành IPC dễ dãi, y như một lời call hàm thông thường. RPC hoàn toàn có thể được thực hiện giữa hai tiến triền trên cùng một máy tính, hoặc thân những máy tính xách tay khác nhau vào mạng.

Bạn đang xem: Rpc là gì? các thức hoạt động của rpc

Microsoft Windows API cung cấp cơ chế RPC theo đúng xuất hiện Software Foundation (OSF) Distributed Computing Environment (DCE). Có nghĩa là, bất cứ vận dụng như thế nào áp dụng RPC phụ thuộc Windows API, trọn vẹn rất có thể Bàn bạc cùng với vận dụng khác áp dụng RPC theo chuẩn DCE.

Thuật ngữ:

interface: Giao diện biểu lộ phương pháp tiếp xúc của RPC. RPC sử dụng một ngôn từ đặc trưng nhằm biểu thị interface, sẽ là Interface Definition Language (IDL). IDL của Microsoft là Microsoft Interface Definition Language (MIDL).Remote Procedure : là các hàm được xây dựng theo đúng interface tư tưởng trước.Client: là lịch trình áp dụng RPC để thực hiện một nhiệm vụ.Server là lịch trình dấn các thử dùng từ client, triển khai trách nhiệm định trước, vấn đáp tác dụng đến client.

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

Trình biên dịch MIDL (MIDL compiler)Các thỏng viện liên kết động (Rpcrt4.dll)Name service providerEndpoint mapper

Microsoft Interface Definition Language (MIDL)

Đây là ngôn từ diễn tả interface được Microsoft áp dụng. Viết một file IDL tương tự như nlỗi lúc quan niệm header vào ngữ điệu C, tuy vậy bản thân ngữ điệu này có thêm một vài từ khoá khác biệt. IDL triệu tập biểu đạt trực thuộc tính của hàm với các tyêu thích số của hàm. Sau khi miêu tả IDL ngừng, nó cần được dịch thành những tệp tin .c cùng .h trải qua MIDL compiler.

Để dễ dàng nắm bắt, tôi đang ban đầ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 & press . Enter QUIT to exit. "); do memset(buf, 0, sizeof(buf)); if (fgets(buf, 256, stdin)== NULL) break; SayYouDo(buf); while (strcmp(buf, "QUIT "));Logic của chương trình này vô cùng solo 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 đưa ra là nếu viết lại lịch trình này, cố gắng lời hotline hàm SayYouDo() thành RPC thì đã thay nào?

Xây dựng file IDL

// File SayYouDo.idl// Compiling SayYouDo.idl: // midl /app_config SayYouDo.idl< // interface chất lượng 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 riêng biệt cùng nhau trải qua uuid. Giá trị này đề nghị là nhất. UUID có thể sinh ra bởi phương tiện Create UUID của Microsoft. Công thay này còn có sẵn trong bộ Visual Studio.

*

version: cho thấy thêm phiên phiên bản của interface. Trong ví dụ này là 1 trong những.0

binding handle:

Để đọc có mang này, nên gọi Binding là 1 quá trình thiết lập cấu hình một kết nối xúc tích và ngắn gọn (logical connection) thân công tác client và công tác hệ thống. Thông tin về liên kết nữa client với hệ thống được màn biểu diễn thông qua 1 cấu tạo, hotline là binding handle.

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

Có 3 các loại binding handle rất có thể cần sử dụng được, bao gồm: implicit_handle, auto_handle explicit_handle.

implicit_handle tức là binding handle được gọi ngầm định, không nhất thiết phải có vào tmê mẩn số lúc gọi hàm RPC. Nên cần sử dụng loại này.explicit_handle có nghĩa là binding handle được đọc tường minch, buộc phải có vào tsi số Lúc call hàm RPC. Đây là tđam mê số trước tiên của hàm.

Xem thêm:

auto_handle: hoàn toàn có thể đọc là mẫu mã phối hợp của 2 hình dáng trên.

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

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

interface: Định nghĩa interface bao hàm tên hàm và những tđê mê số. Các tyêu thích số bắt buộc có mang rõ hình trạng tài liệu . Thuộc tính của các ngôi trường dữ liệu vào ngữ điệu IDL rất có thể tham khảo ở đây: IDL Attributes

Compile MIDL file

Sử dụng MIDL Compiler nhằm sinc code cho client và VPS. Quá trình này sẽ khởi tạo ra 3 file:

SayYouDo.h: Header cho cả client cùng server

SayYouDo_c.c: Client stub

SayYouDo_s.c: VPS stub

Trong quá trình biên dịch, buộc phải lưu giữ ý: chọn đúng gốc rễ (x86, x64 giỏi ia64) Khi biên dịch. Tham số này rất có thể tìm hiểu thêm trải 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

Cmùi hương trình đã đăng kí một interface cùng với khố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 kinh nghiệm phiên bản thân, chúng ta đề xuất cần sử dụng hàm RpcServerRegisterIf2 hoặc RpcServerRegisterIfEx chũm cho RpcServerRegisterIf lúc đăng kí interface. Nên thiết lập cờ RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH Khi đăng kí interface, IfCallbackFn thì rất có thể tùy chỉnh cấu hình hoặc đặt bằng NULL.

Vấn đề này đang tránh đến client ( xin kể lại là client) bị crash thân chừng lúc kết nối tới RPC VPS. Lỗi này tương đối cạnh tranh 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 khi cụ liên kết tới VPS. Các bạn sẽ không khi nào dùng hàm NdrClientCall2 trong code của chúng ta, NdrClientCall2 được hình thành auto trong client code stub.

RpcServerListen để bắt đàu nhấn liên kết tự client. Sau hàm này, VPS có thể xem là chuẩn bị sẵn sàng.

Implement interface

ở đây, bản thân implement cho 2 hàm SayYouDo với ShutdownRpc.

Phía VPS buộc phải implement 2 hàm đến làm chủ cỗ nhớ:Hai hàm này được sử dụng lúc 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 VPS, chúng ta sử dụng hàm RpcMgmtStopServerListening. Để biết lúc nào tắt hệ thống, thì rất có thể tinh chỉnh qua client nhỏng bản thân làm cho.

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 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 khổng lồ 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 áp dụng RpcStringBindingCompose để chế tạo ra binding string với biến đổi string thành binding handle trải qua hàm RpcBindingFromStringBinding

Client cũng cần được 2 hàm đến vấn đề quản lý bộ nhớ lưu trữ rượu cồn, như làm việc hệ thống.

Xem thêm: Đối Tác Chiến Lược Tiếng Anh Là Gì, Đối Tác Chiến Lược

Sau Lúc tạo thành handle thành công, client vẫn hotline hàm thông qua RPC nhỏng sau:

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

Compile and Link

*

*

Lưu ý khi dùng explicit_handle

Trong ngôi trường hòa hợp dùng explicit_handle thì nên khai báo nlỗi sau:

// File SayYouDo.idl// Compiling SayYouDo.idl: // midl /app_config SayYouDo.idl< // interface quality 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 lớn 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à cục bộ mã mối cung cấp công tác mẫu: RpcExample.


Chuyên mục: Tổng Hợp