Menemukan Sistem Host Server

Sistem host server adalah komputer yang menjalankan program server aplikasi terdistribusi. Mungkin ada satu atau banyak sistem host server di jaringan. Bagaimana program klien Anda menemukan server untuk disambungkan tergantung pada kebutuhan program Anda.

Ada dua metode untuk menemukan sistem host server:

  • Menggunakan informasi yang disimpan dalam string dalam kode sumber klien, variabel lingkungan, atau file konfigurasi khusus aplikasi. Aplikasi klien Anda dapat menggunakan data dalam string untuk menyusun pengikatan antara klien dan server.
  • Mengkueri database layanan nama untuk lokasi program server.

Bagian ini menyajikan informasi tentang kedua teknik ini dalam topik berikut:

Menggunakan Pengikatan String

Aplikasi dapat membuat pengikatan dari informasi yang disimpan dalam string. Aplikasi klien Anda menyusun informasi ini sebagai string, lalu memanggil fungsi RpcBindingFromStringBinding . Klien harus menyediakan informasi berikut untuk mengidentifikasi server:

(UUID objek dan informasi titik akhir bersifat opsional.)

Dalam contoh berikut, parameter pszNetworkAddress dan parameter lainnya termasuk garis miring tersemat. Garis miring terbelakang adalah karakter escape dalam bahasa pemrograman C. Dua garis miring terbelakang diperlukan untuk mewakili setiap karakter garis miring terbelakang harfiah tunggal. Struktur pengikatan string harus berisi empat karakter garis miring terbalik untuk mewakili dua karakter garis miring terbalik harfiah yang mendahului nama server.

Contoh berikut menunjukkan bahwa nama server harus didahului oleh delapan garis miring terbalik sehingga empat karakter garis miring terbalik harfiah akan muncul dalam struktur data pengikatan string setelah fungsi sprintf_s memproses string.

/* client application */

char * pszUuid = "6B29FC40-CA47-1067-B31D-00DD010662DA";
char * pszProtocol = "ncacn_np";
char * pszNetworkAddress = "\\\\\\\\servername";
char * pszEndpoint = "\\\\pipe\\\\pipename";
char * pszString;
 
int len = 0;
 
len  = sprintf_s(pszString, strlen(pszUuid), "%s", pszUuid);
len += sprintf_s(pszString + len, strlen(pszProtocolSequence) + 2, "@%s:",
    pszProtocolSequence);
if (pszNetworkAddress != NULL)
    len += sprintf_s(pszString + len, strlen(pszNetworkAddress), "%s",
    pszNetworkAddress);
len += sprintf_s(pszString + len, strlen(pszEndpoint) + 2, "[%s]", pszEndpoint);

Dalam contoh berikut, pengikatan string muncul sebagai:

6B29FC40-CA47-1067-B31D-00DD010662DA@ncacn_np:\\\\servername[\\pipe\\pipename]

Klien kemudian memanggil RpcBindingFromStringBinding untuk mendapatkan handel pengikatan:

RPC_BINDING_HANDLE hBinding;
 
status = RpcBindingFromStringBinding(pszString, &hBinding);
//...

Fungsi kenyamanan, RpcStringBindingCompose merakit objek UUID, urutan protokol, alamat jaringan, dan titik akhir dalam sintaks yang benar untuk panggilan ke RpcBindingFromStringBinding. Anda tidak perlu khawatir tentang menempatkan ampersand, titik dua, dan berbagai komponen untuk setiap urutan protokol di tempat yang tepat; Anda hanya menyediakan string sebagai parameter ke fungsi . Pustaka run-time bahkan mengalokasikan memori yang diperlukan untuk pengikatan string.

char * pszNetworkAddress = "\\\\server";
char * pszEndpoint = "\\pipe\\pipename";
status = RpcStringBindingCompose(
            pszUuid,
            pszProtocolSequence,
            pszNetworkAddress,
            pszEndpoint,
            pszOptions,
            &pszString);
//...
status = RpcBindingFromStringBinding(
            pszString,
            &hBinding);
//...

Fungsi kenyamanan lainnya, RpcBindingToStringBinding, mengambil handel pengikatan sebagai input dan menghasilkan pengikatan string yang sesuai.

Mengimpor dari Database Layanan Nama

Database layanan nama menyimpan, antara lain, handel pengikatan dan UUID. Aplikasi klien Anda dapat mencari salah satu atau kedua hal ini ketika perlu mengikat server. Untuk diskusi tentang informasi yang disimpan layanan nama, dan format penyimpanan, lihat Database Layanan Nama RPC.

Pustaka RPC menyediakan dua set fungsi yang dapat digunakan program klien Anda untuk mencari database layanan nama. Nama-nama satu set dimulai dengan RpcNsBindingImport. Nama-nama set lain dimulai dengan RpcNsBindingLookup. Perbedaan antara dua grup fungsi adalah bahwa fungsi RpcNsBindingImport mengembalikan satu handel pengikatan per panggilan dan fungsi RpcNsBindingLookup mengembalikan grup handel per panggilan.

Untuk memulai pencarian dengan fungsi RpcNsBindingImport, pertama-tama panggil RpcNsBindingImportBegin, seperti yang ditunjukkan pada fragmen kode berikut.

RPC_STATUS status;
RPC_NS_HANDLE hNameServiceHandle;
 
status = RpcNsBindingImportBegin(
    RPC_C_NS_SYNTAX_DEFAULT,
    NULL,
    MyInterface_v1_0_c_ifspec,
    NULL,
    &hNameServiceHandle);

Ketika fungsi RPC mencari database layanan nama, mereka memerlukan tempat untuk memulai pencarian. Dalam terminologi RPC, ini disebut nama entri. Program klien Anda meneruskan nama entri sebagai parameter kedua ke RpcNsBindingImportBegin. Parameter ini bisa NULL jika Anda ingin mencari seluruh database layanan nama. Atau, Anda dapat mencari entri server dengan meneruskan nama entri server atau mencari entri grup dengan meneruskan nama entri grup. Meneruskan nama entri membatasi pencarian ke konten entri tersebut.

Dalam contoh sebelumnya, nilai RPC_C_NS_SYNTAX_DEFAULT diteruskan sebagai parameter pertama ke RpcNsBindingImportBegin. Ini memilih sintaks nama entri default. Saat ini, ini adalah satu-satunya sintaks nama entri yang didukung.

Aplikasi klien Anda dapat mencari database layanan nama untuk nama antarmuka, UUID, atau keduanya. Jika Anda ingin memintanya mencari antarmuka berdasarkan nama, teruskan variabel antarmuka global yang dihasilkan pengkompilasi MIDL dari file IDL Anda sebagai parameter ketiga ke RpcNsBindingImportBegin. Anda akan menemukan deklarasinya di file header yang dihasilkan pengkompilasi MIDL saat menghasilkan stub klien. Jika Anda ingin program klien Anda mencari berdasarkan UUID saja, atur parameter ketiga ke NULL.

Saat mencari database layanan nama untuk UUID, atur parameter keempat RpcNsBindingImportBegin ke UUID yang ingin Anda cari. Jika Anda tidak mencari UUID, atur parameter ini ke NULL.

Fungsi RpcNsBindingImportBegin meneruskan alamat handel konteks layanan-pencarian nama melalui parameter kelimanya. Anda meneruskan parameter ini ke fungsi RpcNsBindingImport lainnya.

Secara khusus, fungsi berikutnya yang akan dipanggil aplikasi klien Anda adalah RpcNsBindingImportNext. Program klien menggunakan fungsi ini untuk mengambil handel pengikatan yang kompatibel dari database layanan nama. Fragmen kode berikut menunjukkan bagaimana fungsi ini mungkin dipanggil:

RPC_STATUS status;
RPC_BINDING_HANDLE hBindingHandle;
// The variable hNameServiceHandle is a valid name service search 
// context handle obtained from the RpcNsBindingBegin function.
 
status = RpcNsBindingImportNext(hNameServiceHandle, &hBindingHandle);

Setelah disebut fungsi RpcNsBindingImportNext untuk mendapatkan handel pengikatan, aplikasi klien Anda dapat menentukan apakah handel yang diterimanya dapat diterima. Jika tidak, program klien Anda dapat menjalankan perulangan dan memanggil RpcNsBindingImportNext lagi untuk melihat apakah layanan nama berisi handel yang lebih tepat. Untuk setiap panggilan ke RpcNsBindingImportNext, harus ada panggilan yang sesuai ke RpcNsBindingFree. Saat pencarian Anda selesai, panggil fungsi RpcNsBindingImportDone untuk membebaskan konteks pencarian.

Setelah aplikasi klien Anda memiliki handel pengikatan yang dapat diterima, aplikasi harus memeriksa untuk memastikan bahwa aplikasi server berjalan. Ada dua metode yang dapat digunakan klien Anda untuk melakukan verifikasi ini. Yang pertama adalah memanggil fungsi di antarmuka klien. Jika program server berjalan, panggilan akan selesai. Jika tidak, panggilan akan gagal. Cara yang lebih baik untuk memverifikasi bahwa server berjalan adalah dengan memanggil RpcEpResolveBinding, diikuti dengan panggilan ke RpcMgmtIsServerListening. Untuk informasi selengkapnya tentang database layanan nama, lihat Database Layanan Nama RPC.