Tarantool CE/EE Documentation portal logo
Помощь

Коннекторы

Коннекторы – это API, с помощью которых можно использовать Tarantool с различными языками программирования.

Коннекторы можно разделить на две группы – поддерживаемые командой Tarantool и поддерживаемые сообществом. Команда Tarantool поддерживает следующие коннекторы:

Все остальные коннекторы поддерживаются сообществом, что означает, что поддержка новых возможностей Tarantool может быть отложена. Все доступные коннекторы перечислены на странице Коннекторы.

Протокол

Бинарный протокол Tarantool разработан с акцентом на асинхронный ввод-вывод и простую интеграцию с прокси. Каждый клиентский запрос начинается с заголовка переменной длины, содержащего идентификатор запроса, тип запроса, идентификатор экземпляра, номер последовательности журнала и т.д.

Обязательное поле длины в заголовке запроса упрощает ввод-вывод на стороне клиента или прокси. Ответ на запрос отправляется клиенту сразу после готовности. В заголовке ответа всегда присутствуют тот же тип и идентификатор, что и в запросе. Идентификатор позволяет сопоставить запрос с ответом, даже если ответы приходят не по порядку.

Если вы не реализуете клиентский драйвер, вам не нужно вникать в детали бинарного протокола. Драйверы для конкретных языков предоставляют удобный способ хранения структур данных предметной области в Tarantool. Полное описание бинарного протокола поддерживается в аннотированной форме Бэкуса-Наура в дереве исходного кода. Подробные примеры и диаграммы всех запросов и ответов бинарного протокола см. в разделе Бинарный протокол.

Пример пакета

API Tarantool предназначен для того, чтобы клиентская программа могла отправить пакет запроса серверному экземпляру и получить ответ. Ниже приведён пример того, что клиент отправляет для box.space[513]:insert{'A', 'BB'}. Описание компонентов в формате BNF приведено на странице Бинарный протокол.

Компонент
Байт #0
Байт #1
Байт #2
Байт #3
код insert
02
остаток заголовка
...
...
...
...
2-значное число: id спейса
cd
02
01
код кортежа
21
1-значное число: полей = 2
92
строка (1 символ): field[1]
a1
41
строка (2 символа): field[2]
a2
42
42

Теперь можно отправить этот пакет экземпляру Tarantool и интерпретировать ответ (на странице Бинарный протокол приведено описание формата пакетов как для запросов, так и для ответов). Однако было бы проще и менее ошибочно вызывать подпрограмму, которая форматирует пакет в соответствии с типизированными параметрами. Например, response = tarantool_routine("insert", 513, "A", "B");. Именно для этого существуют API драйверов для Perl, Python, PHP и т.д.

Настройка сервера для примеров с коннекторами

В этом разделе приведены примеры подключения к экземпляру Tarantool с помощью коннекторов для Perl, PHP, Python, node.js и C. В примерах используются жёстко заданные параметры, и они будут работать только при соблюдении следующих условий:

  • Экземпляр Tarantool (tarantool) запущен на localhost (127.0.0.1) и принимает подключения на порту 3301 (box.cfg.listen = '3301');
  • Спейс examples имеет id = 999 (box.space.examples.id = 999) и первичный индекс по числовому полю (box.space[999].index[0].parts[1].type = "unsigned");
  • Пользователь guest имеет права на чтение и запись.

Выполнить все эти условия можно, запустив экземпляр и выполнив следующий скрипт:

box.cfg{listen=3301}box.schema.space.create('examples',{id=999})box.space.examples:create_index('primary', {type = 'hash', parts = {1, 'unsigned'}})box.schema.user.grant('guest','read,write','space','examples')box.schema.user.grant('guest','read','space','_space')

Интерпретация возвращаемых значений функций

При вызове функции через Tarantool с использованием любого коннектора возвращаемое значение представлено в формате MsgPack. Если функция вызывается через API коннектора, могут выполняться некоторые преобразования. Все скалярные значения возвращаются в виде кортежей (с идентификатором типа MsgPack, за которым следует значение); все нескалярные значения возвращаются в виде группы кортежей (с идентификатором массива MsgPack, за которым следуют скалярные значения). Если функция вызывается через командный слой бинарного протокола – «eval» – а не через API коннектора, преобразования не выполняются.

В следующем примере создаётся Lua-функция. Поскольку к ней будет внешний доступ от имени пользователя guest, потребуется LINK_NOT_DEFINED(../reference/reference_lua/box/box_schema/user_grant) привилегии на выполнение. Функция возвращает пустой массив, скалярную строку, два логических значения и короткое целое число. Значения соответствуют описанным в таблице Стандартные типы и кодировки MsgPack.

tarantool> box.cfg{listen=3301}2016-03-03 18:45:52.802 [27381] main/101/interactive I> ready to accept requests---...tarantool> function f() return {},'a',false,true,127; end---...tarantool> box.schema.func.create('f')---...tarantool> box.schema.user.grant('guest','execute','function','f')---...

Ниже приведена программа на C, вызывающая эту функцию. Хотя в примере используется C, результат будет точно таким же, если вызывающая программа написана на Perl, PHP, Python, Go или Java.

#include <stdio.h>#include <stdlib.h>#include <tarantool/tarantool.h>#include <tarantool/tnt_net.h>#include <tarantool/tnt_opt.h>void main() {  struct tnt_stream *tnt = tnt_net(NULL);              /* НАСТРОЙКА */  tnt_set(tnt, TNT_OPT_URI, "localhost:3301");   if (tnt_connect(tnt) < 0) {                         /* ПОДКЛЮЧЕНИЕ */       printf("Connection refused\n");       exit(-1);   }   struct tnt_stream *arg; arg = tnt_object(NULL);     /* ФОРМИРОВАНИЕ ЗАПРОСА */   tnt_object_add_array(arg, 0);   struct tnt_request *req1 = tnt_request_call(NULL);  /* ВЫЗОВ функции f() */   tnt_request_set_funcz(req1, "f");   uint64_t sync1 = tnt_request_compile(tnt, req1);   tnt_flush(tnt);                                     /* ОТПРАВКА ЗАПРОСА */   struct tnt_reply reply;  tnt_reply_init(&reply);    /* ПОЛУЧЕНИЕ ОТВЕТА */   tnt->read_reply(tnt, &reply);   if (reply.code != 0) {     printf("Call failed %lu.\n", reply.code);     exit(-1);   }   const unsigned char *p= (unsigned char*)reply.data; /* ВЫВОД ОТВЕТА */   while (p < (unsigned char *) reply.data_end)   {     printf("%x ", *p);     ++p;   }   printf("\n");   tnt_close(tnt);                                     /* ЗАВЕРШЕНИЕ */   tnt_stream_free(arg);   tnt_stream_free(tnt);}

При выполнении этой программы будет выведено:

dd 0 0 0 5 90 91 a1 61 91 c2 91 c3 91 7f

Первые пять байтов – dd 0 0 0 5 – это кодировка MsgPack для «32-битного заголовка массива со значением 5» (см. спецификацию MsgPack). Остальные байты соответствуют описанию в таблице Стандартные типы и кодировки MsgPack.