1 / 26

Zdalne wywołania procedur

Jarosław Kuchta Programowanie Współbieżne. Zdalne wywołania procedur. Podstawy. RPC – Remote Procedure Call Wywołanie procedur jednego procesu z innego procesu. Proces wywoływany – serwer Proces wywołujący - klient

nelia
Download Presentation

Zdalne wywołania procedur

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Jarosław Kuchta Programowanie Współbieżne Zdalne wywołania procedur

  2. Podstawy • RPC – Remote Procedure Call • Wywołanie procedur jednego procesu z innego procesu. • Proces wywoływany – serwer • Proces wywołujący - klient • Wywoływana procedura jest wykonywana w przestrzeni adresowej wywoływanegoprocesu (serwera). RPC

  3. RPC w sieci • protokół opracowany przez firmę Sun • popularny w systemie Unix • obsługiwany w bibliotekach języka Java • współcześnie obsługiwany przez protokoły: • SOAP • CORBA • XML-RPC • JSON-RPC RPC

  4. XDR – External Data Representation • standard jednolitej reprezentacji danych • w sieci między komputerami o różnych architekturach • warunki podstawowe • wszystkie typy danych mają rozmiar będący wielokrotnością 4 bajtów, • liczby całkowite kodowane w standardzie BigEndian (najpierw starsze bajty) • liczby rzeczywiste w formacie IEEE. • nadawca i odbiorca muszą znać struktury danych (nie są przekazywane) RPC

  5. Filtry XDR • xdr_int • xdr_float • xdr_char • xdr_wrapstring (dla typu char *) RPC

  6. Filtry XDR dla struktur • struktura • struct s { int i, float x } • filtr • int xdr_s (XDR *xptr, struct s *sptr) { return (xdr_int(xptr, &sptr->i) && xdr_float(xptr, &sptr->x); } RPC

  7. Identyfikacja procedury • trzy liczby całkowite: • numer programu • numer wersji • numer procedury RPC

  8. Rejestracja procedury • int registerrpc( • unsigned long PROG, • unsigned long VERS, • unsigned long PROC, • char * ( * proc)(), // adres procedury • int (* xdr_arg)(), // adres filtra argumentów • int (* xdr_res)()); // adres filtra wyników RPC

  9. #include <rpc/rpc.h> #define PRZYKLAD 0x20000000 #define WERSJA 1 #define CZAS 1 typedef struct { … } tt; extern void podaj_czas (tt *) { … } char *czas (void) { static tt t; podaj_czas (&t); return (char *)&t; } void main (void) { registerrpc ( PRZYKŁAD, WERSJA, CZAS, czas, xdr_void, xdr_t); svc_run(); } Przykład – procedura udostępniająca czas systemowy RPC

  10. Wywołanie procedury zdalnej • int callrpc( • char *server, // nazwa serwera • unsigned long PROG, • unsigned long VERS, • unsigned long PROC, • int (* xdr_arg)(), • char *arg, // struktura argumentów • int (* xdr_res)(), • char *res); // struktura wyników RPC

  11. #include <rpc/rpc.h> #define PRZYKLAD 0x20000000 #define WERSJA 1 #define CZAS 1 typedef struct { … } tt; int xdr_t (XDR *xptr, tt *tp) { … } extern void korzystaj (tt *); void main (void) { tt t; callrpc("servername", PRZYKŁAD, WERSJA, CZAS, xdr_void, NULL, xdr_t, &t); korzystaj (&t); } Przykład – wywołanie procedury udostępniającej czas systemowy RPC

  12. RPC a wykonanie równoległe zwykłe wywołanie RPC wywołanie przez rozgłaszanie main proc main proc proc registerrpc registerrpc callrpc clnt_broadcast proces wywołujący jest wstrzymywany procesy wywoływane są równolegle RPC

  13. Wykonanie równoległe – przez rozgłaszanie • int clnt_broadcast( • unsigned long PROG, • unsigned long VERS, • unsigned long PROC, • int (* xdr_arg)(), • char *arg, • int (* xdr_res)(), • char *res, • int (* res_proc)()); RPC

  14. #include <rpc/rpc.h> #define PRZYKLAD 0x20000000 #define WERSJA 1 #define CZAS 1 typedef struct { … } tt; int xdr_t (XDR *xptr, tt *tp) { … } extern void korzystaj (tt *); int po_rozgloszeniu (char *t, struct socketaddr_in *addr) { return true; } void main (void) { tt t; clnt_broadcast( PRZYKŁAD, WERSJA, CZAS, xdr_void, NULL, xdr_t, &t, po_rozgloszeniu); korzystaj (&t); } Przykład – wywołanie procedury przez rozgłaszanie RPC

  15. Ograniczenia • Brak mechanizmu wstrzymywania procesów • rozwiązanie: wysokopoziomowe mechanizmy synchronizacji • w Unix RPC – blokowanie procesu wywoływanego • konieczność jawnego podawania nazwy serwera • rozwiązanie: rpc_bind • zdalne rozgłaszanie – przynajmniej jedna procedura musi być wykonywana RPC

  16. Asynchroniczne RPC – deklaracja procedury (IDL) [ uuid (7f6c4340-eb67-11d1-b9d7-00c04fad9a3b), version(1.0), pointer_default(unique) ] interface AsyncRPC { const long DEFAULT_ASYNC_DELAY = 10000; const short APP_ERROR = -1; const char* DEFAULT_PROTOCOL_SEQUENCE = "ncacn_ip_tcp"; const char* DEFAULT_ENDPOINT = "8765"; void NonAsyncFunc(handle_t hBinding, [in, string] unsigned char * pszMessage); void AsyncFunc(handle_t hBinding, [in] unsigned long nAsychDelay); void Shutdown(handle_t hBinding); } RPC

  17. IDL • IDL – Interface Description Language • MIDL – kompilator IDL RPC

  18. Alternatywa – atrybuty ACF • ACF – Application Configuration File • IDL + ACF: interface AsyncRPC { [async] AsyncFunc(); } RPC

  19. Wywołanie asynchroniczne (1) RPC_ASYNC_STATE Async; RPC_STATUS status; // Initialize the handle. status = RpcAsyncInitializeHandle(&Async, sizeof(RPC_ASYNC_STATE)); if (status) { // Code to handle the error goes here. } Async.UserInfo = NULL; Async.NotificationType = RpcNotificationTypeEvent; Async.u.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (Async.u.hEvent == 0) { // Code to handle the error goes here. } RPC

  20. Wywołanie asynchroniczne (2) // Call an asynchronous RPC routine here RpcTryExcept { printf("\nCalling the remote procedure 'AsyncFunc'\n"); AsyncFunc(&Async, AsyncRPC_ClientIfHandle, nAsychDelay); } RpcExcept(1) { ulCode = RpcExceptionCode(); printf("AsyncFunc: Run time reported exception 0x%lx = %ld\n", ulCode, ulCode); } RpcEndExcept RPC

  21. Wywołanie synchroniczne tej samej procedury // Call a synchronous routine while the asynchronous procedure is still running RpcTryExcept { printf("\nCalling the remote procedure 'NonAsyncFunc'\n"); NonAsyncFunc(AsyncRPC_ClientIfHandle, pszMessage); fprintf(stderr, "While 'AsyncFunc' is running asynchronously,\n" "we still can send message to the server in the mean time.\n\n"); } RpcExcept(1) { ulCode = RpcExceptionCode(); printf("NonAsyncFunc: Run time reported exception 0x%lx = %ld\n", ulCode, ulCode); } RpcEndExcept RPC

  22. Oczekiwanie na odpowiedź • bez blokowania własnego wątku: // This code fragment assumes that Async is a valid asynchronous RPC handle. if (WaitForSingleObject(Async.u.hEvent, INFINITE) == WAIT_FAILED) { RpcRaiseException(APP_ERROR); } • z blokowaniem własnego wątku: if (SleepEx(INFINITE, TRUE) != WAIT_IO_COMPLETION) { RpcRaiseException(APP_ERROR); } RPC

  23. Obsługa wywołania przez serwer (1) void AsyncFunc(IN PRPC_ASYNC_STATE pAsync, IN RPC_BINDING_HANDLE hBinding, IN OUT unsigned long nAsychDelay) { int nReply = 1; RPC_STATUS status; unsigned long nTmpAsychDelay; int i; if (nAsychDelay < 0) nAsychDelay = DEFAULT_ASYNC_DELAY; else if (nAsychDelay < 100) nAsychDelay = 100; RPC

  24. // We only call RpcServerTestCancel if the call // takes longer than ASYNC_CANCEL_CHECK ms if (nAsychDelay > ASYNC_CANCEL_CHECK) { nTmpAsychDelay = nAsychDelay/100; for (i = 0; i < 100; i++) { Sleep(nTmpAsychDelay); if (i%5 == 0) { fprintf(stderr, "\rRunning AsyncFunc (%lu ms) (%d%c) ... ", nAsychDelay, i+5, PERCENT); status = RpcServerTestCancel( RpcAsyncGetCallHandle(pAsync)); if (status == RPC_S_OK) { fprintf(stderr, "\nAsyncFunc has been canceled!!!\n"); break; } else if (status != RPC_S_CALL_IN_PROGRESS) { printf("RpcAsyncInitializeHandle returned 0x%x\n", status); exit(status); } } } } else Sleep(nAsychDelay); Obsługa wywołania przez serwer (2) RPC

  25. Wysłanie odpowiedzi przez serwer printf("\nCalling RpcAsyncCompleteCall\n"); status = RpcAsyncCompleteCall(pAsync, &nReply); printf("RpcAsyncCompleteCall returned 0x%x\n", status); if (status) exit(status); } RPC

  26. Przyjęcie odpowiedzi przez klienta status = RpcAsyncCompleteCall( &Async, &Reply); // W tym momencie wynik jest zwracany w Reply RPC

More Related