Remote Procedure Call

Trong khi thiết kế ứng dụng, bao gồm vận dụng được xây cất thành các quy trình khác nhau, chạy đôi khi. Các các bước này rất có thể vận động trên cùng một khối hệ thống, hoặc chuyển động bên trên các hệ thống không giống nhau. Các quy trình này thảo luận tài liệu hỗ tương với nhau, quy trình này call là Interprocess Communications (IPC). Remote Procedure Điện thoại tư vấn (RPC) là 1 trong phương pháp dùng làm dàn xếp dữ liệu. RPC để cho Việc triển khai IPC thuận lợi, y hệt như một lời điện thoại tư vấn hàm bình thường. RPC có thể được thực hiện giữa hai tiến triền bên trên cùng một máy tính, hoặc giữa những máy tính khác nhau trong mạng.

Bạn đang xem: Rpc là gì

Microsoft Windows API hỗ trợ hiệ tượng RPC theo đúng xuất hiện Software Foundation (OSF) Distributed Computing Environment (DCE). Tức là, bất kỳ ứng dụng làm sao thực hiện RPC nhờ vào Windows API, hoàn toàn rất có thể hiệp thương với vận dụng khác sử dụng RPC theo chuẩn DCE.

Thuật ngữ:

interface: Giao diện trình bày phương pháp tiếp xúc của RPC. RPC sử dụng một ngữ điệu quan trọng đặc biệt để biểu đạt 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 tuân thủ theo đúng interface khái niệm trước.Client: là công tác áp dụng RPC nhằm tiến hành một trọng trách.Server là công tác dấn những đòi hỏi trường đoản cú client, thực hiện nhiệm vụ định trước, trả lời hiệu quả mang đến client.

Các thành phần thiết yếu của Microsoft RPC:

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

Microsoft Interface Definition Language (MIDL)

Đây là ngôn ngữ diễn tả interface được Microsoft áp dụng. Viết một file IDL cũng tương tự như khi quan niệm header trong ngôn từ C, tuy thế bạn dạng thân ngôn từ này có thêm một vài ba keyword khác hoàn toàn. IDL triệu tập thể hiện ở trong tính của hàm với các ttê mê số của hàm. Sau lúc biểu hiện IDL kết thúc, nó cần phải dịch thành những tệp tin .c với .h thông qua MIDL compiler.

Để dễ dàng nắm bắt, tôi đang bắt đầu bởi 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 lớn exit. "); vì 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 xiết đối kháng giản:

Đợi người dùng nhập dữ liệu, hiển thị nó ra screen.Nếu người dùng nhập QUIT, thì hiển thị QUIT và bay.

Câu hỏi đưa ra là trường hợp viết lại lịch trình này, rứa lời Hotline hàm SayYouDo() thành RPC thì vẫn ráng nào?

Xây dựng tệp tin 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ả trên bao gồm:UUID: Các interface được phân minh cùng nhau trải qua uuid. Giá trị này buộc phải là nhất. UUID rất có thể ra đời bằng vẻ ngoài Create UUID của Microsoft. Công cầm cố này còn có sẵn trong cỗ Visual Studio.

*

version: cho biết thêm 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, đề xuất đọc Binding là một trong những quy trình thiết lập một kết nối logic (logical connection) giữa công tác client và công tác hệ thống. tin tức về liên kết nữa client cùng hệ thống được trình diễn thông qua một cấu trúc, call là binding handle.

Trên thực tiễn, RPC client và RPC hệ thống hoàn toàn có thể nằm trên và một laptop hoặc bên trên 2 máy tính xách tay khác nhau. Client với hệ thống hoàn toàn có thể tiếp xúc thông qua nhiều nhiều loại giao thức khác biệt (TCPhường, Named pipe, ...). Về phương diện súc tích, client với hệ thống chỉ phát âm là sẽ liên kết với nhau trải qua binding handle nhưng ko yêu cầu đọc căn nguyên giao tiếp bên dưới (TCP.., Named pipe, ...) vẫn cần sử dụng là gì. Tđam mê khảo danh sách các Protocol có thể sử dụng được: Protocol Sequence.

Có 3 các loại binding handle hoàn toàn 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 hiểu ngầm định, không nhất thiết phải gồm vào tmê mệt số Khi call hàm RPC. Nên sử dụng loại này.explicit_handle Tức là binding handle được đọc tường minc, nên tất cả trong tmê say số khi điện thoại tư vấn hàm RPC. Đây là tđắm đuối số thứ nhất của hàm.

Xem thêm: Artemia Là Gì - Hướng Dẫn Nuôi Artemia Sinh Khối

auto_handle: rất có thể hiểu là hình dáng phối hợp của 2 mẫu mã bên trên.

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

tùy lựa chọn /app_config có thể chấp nhận được sử dụng một vài từ khoá của Application Configuration File (ACF) bên trong file IDL.

interface: Định nghĩa interface bao hàm tên hàm với các tđắm say số. Các tmê mệt số đề xuất quan niệm rõ thứ hạng dữ liệu . Thuộc tính của những ngôi trường dữ liệu vào ngôn ngữ IDL hoàn toàn có thể tìm hiểu thêm sinh sống đây: IDL Attributes

Compile MIDL file

Sử dụng MIDL Compiler nhằm sinh code cho client với hệ thống. 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 quy trình biên dịch, cần lưu giữ ý: lựa chọn đúng căn nguyên (x86, x64 giỏi ia64) khi biên dịch. Tđê mê số này hoàn toàn có thể xem thêm trải 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

Chương trình sẽ đăng kí một interface cùng với khối hệ thống trải 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 bạn dạng thân, chúng ta yêu cầu dùng hàm RpcServerRegisterIf2 hoặc RpcServerRegisterIfEx ráng cho RpcServerRegisterIf Lúc đăng kí interface. Nên tùy chỉnh thiết lập cờ RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH khi đăng kí interface, IfCallbackFn thì hoàn toàn có thể thiết lập hoặc đặt bằng NULL.

Điều này đã rời mang đến client ( xin kể lại là client) bị crash thân chừng Lúc kết nối tới RPC hệ thống. Lỗi này khá nặng nề chịu! Client sẽ bị crash Lúc Call hàm NdrClientCall2, trong khi núm liên kết cho tới server. Các các bạn sẽ không bao giờ dùng hàm NdrClientCall2 vào code của chúng ta, NdrClientCall2 được hình thành tự động hóa vào client code stub.

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

Implement interface

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

Phía server buộc phải implement 2 hàm cho làm chủ bộ nhớ:Hai hàm này được áp dụng Khi hệ thống cấp phép bộ lưu trữ rượu cồn khi 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 bao giờ tắt server, thì hoàn toàn có thể điều khiển qua client như mình 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 to bind to lớn.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 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 sử dụng RpcStringBindingCompose để tạo thành binding string với biến hóa string thành binding handle trải qua hàm RpcBindingFromStringBinding

Client cũng cần phải 2 hàm cho câu hỏi quản lý bộ nhớ lưu trữ cồn, nlỗi sống server.

Xem thêm: Black Death Là Gì - Dịch Hạch Lại Ám Ảnh Nước Mỹ

Sau Lúc chế tạo handle thành công xuất sắc, client đã đ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 sử dụng explicit_handle

Trong ngôi trường hòa hợp sử dụng explicit_handle thì nên cầ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 to 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ã nguồn chương trình mẫu: RpcExample.


Chuyên mục: KHÁI NIỆM LÀ GÌ
Bài viết liên quan

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *