Реализация сущности Client в примере echo
В коде сущности Client
используются транспортные типы и методы, которые будут сгенерированы во время сборки решения компилятором NK на основе IDL-описания интерфейса Ping
.
Однако чтобы получить необходимые для реализации сущности описания типов и сигнатуры методов, вы можете воспользоваться компилятором NK непосредственно после создания EDL-описания сущности, CDL-описаний компонентов и IDL-описаний используемых интерфейсов взаимодействия. В результате необходимые типы и сигнатуры методов будут объявлены в сгенерированных файлах *.h
.
В реализации сущности Client
необходимо:
- Получить клиентский IPC-дескриптор соединения (канала), используя функцию локатора сервисов
ServiceLocatorConnect()
.На вход нужно передать имя IPC-соединения
server_connection
, заданное ранее в файле init.yaml. - Инициализировать транспорт
NkKosTransport
, передав полученный IPC-дескриптор в функциюNkKosTransport_Init()
. - Получить идентификатор необходимого интерфейса (
RIID
), используя функцию локатора сервисовServiceLocatorGetRiid()
. - На вход нужно передать полное имя реализации интерфейса
Ping
. Оно состоит из имен экземпляра компонента (Echo.ping
) и интерфейса (ping
), заданных ранее в Server.edl и Ping.cdl. - Инициализировать прокси-объект, передав транспорт и идентификатор интерфейса в функцию
Ping_proxy_init()
. - Подготовить структуры запроса и ответа.
- Вызвать интерфейсный метод
Ping_Ping()
, передав прокси-объект, а также указатели на запрос и ответ.
client.c
/* Файлы, необходимые для инициализации транспорта. */
/* Описание интерфейса сервера, по которому обращается клиентская сущность. */
/* Точка входа в клиентскую сущность. */
int main(int argc, const char *argv[])
{
NkKosTransport transport;
struct echo_Ping_proxy proxy;
int i;
fprintf(stderr, "Hello I'm client\n");
/* Получаем клиентский IPC-дескриптор соединения с именем
* "server_connection". */
Handle handle = ServiceLocatorConnect("server_connection");
assert(handle != INVALID_HANDLE);
/* Инициализируем IPC-транспорт для взаимодействия с серверной сущностью. */
NkKosTransport_Init(&transport, handle, NK_NULL, 0);
/* Получаем Runtime Interface ID (RIID) для интерфейса echo.Ping.ping.
* Здесь ping – имя экземпляра компонента echo.Ping,
* echo.Ping.ping - имя реализации интерфейса Ping. */
nk_iid_t riid = ServiceLocatorGetRiid(handle, "echo.Ping.ping");
assert(riid != INVALID_RIID);
/* Инициализируем прокси-объект, указав транспорт (&transport)
* и идентификатор интерфейса сервера (riid). Каждый метод
* прокси-объекта будет реализован как отправка запроса серверу. */
echo_Ping_proxy_init(&proxy, &transport.base, riid);
/* Структуры запроса и ответа */
echo_Ping_Ping_req req;
echo_Ping_Ping_res res;
/* Тестовый цикл. */
req.value = EXAMPLE_VALUE_TO_SEND;
for (i = 0; i < 10; ++i)
{
/* Вызываем интерфейсный метод Ping.
* Серверу будет отправлен запрос для вызова метода Ping интерфейса
* ping_comp.ping_impl с аргументом value. Вызывающий поток блокируется
* до момента получения ответа от сервера. */
if (echo_Ping_Ping(&proxy.base, &req, NULL, &res, NULL) == rcOk)
{
/* Выводим значение result, содержащееся в ответе
* (result - выходной аргумент метода Ping). */
fprintf(stderr, "result = %d\n", (int) res.result);
/* Помещаем полученное значение result в аргумент value
* для повторной отправки серверу в следующей итерации. */
req.value = res.result;
}
else
fprintf(stderr, "Failed to call echo.Ping.Ping()\n");
}
return EXIT_SUCCESS;
}