В коде сущности server
используются транспортные типы и методы, которые будут сгенерированы во время сборки решения компилятором NK на основе edl-описания сущности server
.
Однако чтобы получить необходимые для реализации сущности типы и сигнатуры методов, вы можете воспользоваться компилятором NK непосредственно после создания edl-описания сущности, cdl-описаний компонентов и idl-описаний используемых интерфейсов взаимодействия. В результате необходимые типы и сигнатуры методов будут объявлены в сгенерированных файлах *.h
.
В реализации сущности server
необходимо:
Ping()
.Сигнатура реализации метода Ping()
должна в точности совпадать с сигнатурой интерфейсного метода IPing_Ping()
, который объявлен в файле ping.idl.h.
ServiceLocatorRegister()
.На вход нужно передать имя IPC-соединения server_connection
, заданное ранее в файле init.yaml.
NkKosTransport
, передав полученный IPC-дескриптор в функцию NkKosTransport_Init()
.ping
, используя функцию ping_component_init()
.server
, используя функцию server_entity_init()
.nk_transport_recv()
.server_entity_dispatch()
.Диспетчер вызовет необходимую реализацию метода на основе полученного от клиента идентификатора интерфейса (RIID
).
client
, вызвав nk_transport_reply()
.server.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
/* Заголовочный файл реализации транспортного уровня для KasperskyOS. */
#include <coresrv/nk/transport-kos.h>
/* Заголовочный файл локатора сервисов. */
#include <coresrv/sl/sl_api.h>
/* Файл server.edl.h будет сгенерирован из файлов server.edl, ping.cdl и
* ping.idl при сборке решения. Файл server.edl.h содержит сгенерированные
* методы и типы, необходимые для обработки обращения к интерфейсу IPing:
* IPing, server_entity_req, server_entity_req_arena_size, server_entity_res,
* server_entity_res_arena_size, ping_component, server_entity,
* server_entity_dispatch и др. */
#include "server.edl.h"
/* Тип объекта, реализующего интерфейс. */
typedef struct IPingImpl {
struct IPing base; /* Базовый интерфейс объекта. */
/* Внутреннее состояние реализации интерфейса IPing. */
int step; /* Значение "шага", которое будет прибавляться к
* входному аргументу value метода Ping. */
} IPingImpl;
/* Реализация метода Ping. */
static nk_err_t Ping_impl(struct IPing *self,
const struct IPing_Ping_req *req,
const struct nk_arena* req_arena,
struct IPing_Ping_res* res,
struct nk_arena* res_arena)
{
IPingImpl *impl = (IPingImpl *)self;
/* К аргументу value, пришедшему в запросе, прибавляем step и помещаем
* результат в аргумент result. */
res->result = req->value + impl->step;
return NK_EOK;
}
/* Конструктор объекта IPing.
* step - число, на которое увеличивается входящее значение. */
struct IPing *CreateIPingImpl(int step)
{
/* Таблица реализаций методов интерфейса IPing. */
static const struct IPing_ops ops = {
.Ping = Ping_impl
};
/* Объект, реализующий интерфейс. */
static struct IPingImpl impl = {
.base = {&ops}
};
impl.step = step;
return &impl.base;
}
int main(void)
{
NkKosTransport transport;
ServiceId iid;
/* Получаем серверный IPC-дескриптор соединения "server_connection". */
Handle handle = ServiceLocatorRegister("server_connection", NULL, 0, &iid);
assert(handle != INVALID_HANDLE);
/* Инициализируем транспорт до клиента. */
NkKosTransport_Init(&transport, handle, NK_NULL, 0);
/* Подготавливаем структуры запроса к сущности server: фиксированную
* часть и арену. Поскольку ни у одного из методов сущности server нет
* агрументов типа sequence, используются только фиксированные части
* запроса и ответа. Арены фактически не используются. Однако в серверные
* методы транспорта (nk_transport_recv, nk_transport_reply) и в
* dispatch-метод server_entity_dispatch необходимо передать валидные
* арены запроса и ответа. */
union server_entity_req req;
char req_buffer[server_entity_req_arena_size];
struct nk_arena req_arena = NK_ARENA_INITIALIZER(req_buffer,
req_buffer + sizeof(req_buffer));
/* Подготавливаем структуры ответа: фиксированную часть и арену. */
union server_entity_res res;
char res_buffer[server_entity_res_arena_size];
struct nk_arena res_arena = NK_ARENA_INITIALIZER(res_buffer,
res_buffer + sizeof(res_buffer));
/* Инициализируем диспетчер компонента ping. 3 – значение "шага",
* которое будет прибавляться к входному аргументу value. */
struct ping_component component;
ping_component_init(&component, CreateIPingImpl(3));
/* Инициализируем диспетчер сущности server. */
struct server_entity entity;
server_entity_init(&entity, &component);
fprintf(stderr, "Hello I'm server\n");
do {
/* Инициализируем размер фиксированной части запроса. */
nk_req_reset(&req);
/* Инициализируем размеры арен запроса и ответа. */
nk_arena_reset(&req_arena);
nk_arena_reset(&res_arena);
/* Ожидаем запрос от клиента. */
if (nk_transport_recv(&transport.base, (struct nk_message *)&req, &req_arena) != NK_EOK)
fprintf(stderr, "nk_transport_recv error\n");
else
/* Обрабатываем полученный запрос, вызывая реализацию
* запрошенного метода Ping (Ping_impl). */
server_entity_dispatch(&entity, &req, &req_arena, &res, &res_arena);
/* Отправляем ответ. */
if (nk_transport_reply(&transport.base, (struct nk_message *)&res, &res_arena) != NK_EOK)
fprintf(stderr, "nk_transport_reply error\n");
} while (true);
return EXIT_SUCCESS;
}
В начало