RPC LÀ GÌ

Remote Procedure Call

Trong lúc lập trình ứng dụng, bao hàm áp dụng được tạo thành nhiều tiến trình không giống nhau, chạy đôi khi. Các tiến trình này có thể hoạt động bên trên và một hệ thống, hoặc chuyển động bên trên những khối hệ thống không giống nhau. Các các bước này trao đổi tài liệu tương hỗ với nhau, quá trình này gọi là Interprocess Communications (IPC). Remote Procedure điện thoại tư vấn (RPC) là một phương thức dùng để điều đình tài liệu. RPC làm cho vấn đề tiến hành IPC dễ dàng, giống hệt như một lời Điện thoại tư vấn hàm bình thường. RPC hoàn toàn có thể được tiến hành thân nhì tiến triền bên trên cùng một laptop, 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ì

Microsoft Windows API cung cấp chính sách RPC tuân thủ theo đúng mở cửa Software Foundation (OSF) Distributed Computing Environment (DCE). tức là, bất kể áp dụng như thế nào thực hiện RPC dựa vào Windows API, trọn vẹn có thể thảo luận cùng với áp dụng không giống thực hiện RPC theo chuẩn chỉnh DCE.

Thuật ngữ:

interface: Giao diện biểu đạt phương thức giao tiếp của RPC. RPC sử dụng một ngôn từ quan trọng đặc biệt nhằm thể hiện interface, chính là Interface Definition Language (IDL). IDL của Microsoft là Microsoft Interface Definition Language (MIDL).Remote Procedure : là những hàm được xây dừng tuân theo interface có mang trước.Client: là chương 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 đòi hỏi tự client, thực hiện nhiệm vụ định trước, trả lời hiệu quả đến client.

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

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

Microsoft Interface Definition Language (MIDL)

Đây là ngôn ngữ trình bày interface được Microsoft thực hiện. Viết một file IDL cũng như nlỗi Khi khái niệm header vào ngôn từ C, tuy nhiên bạn dạng thân ngôn ngữ này còn có thêm 1 vài keyword khác hoàn toàn. IDL tập trung biểu hiện thuộc tính của hàm với các tđê mê số của hàm. Sau lúc biểu thị IDL dứt, nó rất cần phải dịch thành các file .c với .h trải qua MIDL compiler.

Để dễ hiểu, tôi đã 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 và press . Enter QUIT to exit. "); vày 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 khôn cùng 1-1 giản:

Đợi người 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, nắm lời call hàm SayYouDo() thành RPC thì đang cố 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 tách biệt cùng nhau trải qua uuid. Giá trị này cần là tốt nhất. UUID hoàn toàn có thể xuất hiện bằng hình thức Create UUID của Microsoft. Công nuốm này có sẵn vào cỗ Visual Studio.

*

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

binding handle:

Để gọi khái niệm này, yêu cầu phát âm Binding là 1 trong những quy trình thiết lập cấu hình một kết nối súc tích (logical connection) thân công tác client cùng chương trình VPS. tin tức về liên kết nữa client và hệ thống được biểu diễn thông sang 1 kết cấu, Điện thoại tư vấn là binding handle.

Trên thực tiễn, RPC client cùng RPC hệ thống hoàn toàn có thể vị trí và một máy tính hoặc trên 2 laptop không giống nhau. Client với VPS hoàn toàn có thể giao tiếp thông qua nhiều một số loại giao thức khác biệt (TCP, Named pipe, ...). Về mặt lô ghích, client và server chỉ hiểu là đang kết nối cùng nhau trải qua binding handle mà lại ko nên gọi căn cơ tiếp xúc bên dưới (TCP.., Named pipe, ...) đang dùng là gì. Tđắm đuối khảo list các Protocol rất có thể dùng được: Protocol Sequence.

Có 3 nhiều loại binding handle rất 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 trong ttê mê số Khi hotline hàm RPC. Nên dùng nhiều loại này.explicit_handle Có nghĩa là binding handle được hiểu tường minc, đề xuất tất cả trong tđắm đuối số lúc Call hàm RPC. Đây là ttê mê số đầu tiên của hàm.

Xem thêm: Whoosh Là Gì Trong Tiếng Việt? Nghĩa Của Từ : Whoosh

auto_handle: hoàn toàn có thể gọi là thứ hạng phối kết hợp của 2 hình dạng trên.

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

tùy lựa chọn /app_config có thể chấp nhận được thực hiện một số trong những từ khoá của Application Configuration File (ACF) bên trong tệp tin IDL.

interface: Định nghĩa interface bao hàm tên hàm cùng các tmê mệt số. Các tsi số đề nghị khái niệm rõ loại tài liệu . Thuộc tính của các ngôi trường tài liệu vào ngôn từ IDL rất có thể tìm hiểu thêm sinh hoạt đây: IDL Attributes

Compile MIDL file

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

SayYouDo.h: Header cho cả client và server

SayYouDo_c.c: Client stub

SayYouDo_s.c: hệ thống stub

Trong quy trình biên dịch, phải lưu ý: chọn đúng căn nguyên (x86, x64 xuất xắc ia64) Khi biên dịch. Tmê say số này hoàn toàn có thể tìm hiểu thêm thông qua tùy lựa 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 đang đăng kí một interface 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 tay nghề phiên bản thân, các bạn buộc phải cần sử dụng hàm RpcServerRegisterIf2 hoặc RpcServerRegisterIfEx thay mang đến RpcServerRegisterIf Khi đăng kí interface. Nên cấu hình thiết lập cờ RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH Lúc đăng kí interface, IfCallbackFn thì rất có thể thiết lập hoặc đặt bằng NULL.

Vấn đề này đang tránh mang đến client ( xin đề cập lại là client) bị crash giữa chừng lúc kết nối cho tới RPC hệ thống. Lỗi này khá cạnh tranh chịu! Client sẽ bị crash lúc gọi hàm NdrClientCall2, trong những khi gắng liên kết cho tới server. Các bạn sẽ không bao giờ dùng hàm NdrClientCall2 trong code của chúng ta, NdrClientCall2 được ra đời tự động hóa vào client code stub.

RpcServerListen nhằm bắt đàu thừa nhận kết nối từ bỏ client. Sau hàm này, VPS rất có thể xem là chuẩn bị.

Implement interface

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

Phía VPS đề nghị implement 2 hàm cho cai quản cỗ nhớ:Hai hàm này được thực hiện khi khối hệ thống cấp phát bộ nhớ lưu trữ đụ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, bạn dùng hàm RpcMgmtStopServerListening. Để biết khi nào tắt hệ thống, thì rất có thể điều khiển qua client như mình có tác dụng.

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 to.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 nhằm chế tạo ra binding string với thay đổi string thành binding handle trải qua hàm RpcBindingFromStringBinding

Client cũng cần phải 2 hàm cho việc cai quản bộ lưu trữ hễ, nlỗi sống server.

Sau lúc sinh sản handle thành công, client đang call hàm thông qua RPC như sau:

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

Compile và Link

*

*

Lưu ý khi dùng explicit_handle

Trong ngôi trường vừa lòng sử 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 chất lượng 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à toàn bộ mã mối cung cấp công tác mẫu: RpcExample.

| W88Vuive