N2O

ВСТУП

N2O надає спосіб створення, налаштування і запуску довільних додатків та протоколів всередині деяких хостів, в які N2O може бути включений, таких, як cowboy та emqttd. Кожен додаток також може створювати свої сервісні протоколи-процеси, так, як веб-сторінки створюють WebSocket з'єднання, системи управління бізнес-процесами створюють екземпляри процесів, або як чат-додатки створюють процеси управління кімнатами чи персональними чатами. З N2O все управляється протоколами.

N2O поставляється для роботи в двох режимах: 1) всередині n2o_mqtt воркерів; 2) всередині cowboy процесів, реалізованих в n2o_stream. У першому випадку, сервер MQTT використовується між клієнтами та серверними воркерами. У другому випадку, з Erlang процесів задіяні лише клієнти. Ви можете створити власну конфігурацію циклу обробки N2O.

Сам по собі, N2O — це вбудовуваний протокольний цикл n2o_proto, який ви можете включати у свої продукти. Орім цього, він обробляє кеш та сесії з гнучкими n2o_pi процесами без обмеження права власності. А також визначає AES/CBC—128 кодування та BERT/JSON декодер.

ТИПИ

-type formatter() :: binary | json | bert | text | default | atom(). -type response() :: { formatter(), binary() }.
Лістинг 1. Erlang/OTP записи (records)
#ok { data = [] :: term() }. #error { data = [] :: term() }.
Лістинг 2. N2O Протокол
#reply { resp = [] :: [] | response(), req = [] :: [] | term(), state = [] :: [] | term() }. #unknown { data = [] :: [] | binary(), req = [] :: [] | term(), state = [] :: [] | term() }.
Лістинг 3. N2O контекст (State)
#cx { session = [] :: [] | binary(), formatter = bert :: bert | json, actions = [] :: list(tuple()), state = [] :: [] | term(), module = [] :: [] | atom(), lang = [] :: [] | atom(), path = [] :: [] | binary(), node = [] :: [] | atom(), pid = [] :: [] | pid(), vsn = [] :: [] | integer() }).

ПРОТОКОЛ

Хоча всі протоколи додатків в системі вимагають середовище з одним ефектом, або з таким же шляхом обробки помилок, n2o визначає єдиний протокольний цикл, як стек протоколів, для всіх додатків.

В базовому варіанті n2o містить протоколи NITRO та FTP, що дозволяє створювати працюючі в режимі реального часу веб-додатки, з протоколами на основі бінарних, а також — надійний та продуктивний клієнт для вивантаження файлів, разом з протоколом передачі файлів. Для створення NITRO веб-додатків, вам необхідно підключити nitro в залежності.

info(term(),term(),#cx{}) -> #reply{} | #unknown{}.

info/3 — функція зворотнього виклику (колбек) N2O протоколу, яка викликається при кожному вхідному запиті.

RPC MQTT

N2O надає RPC через механізм MQ для MQTT пристроїв. N2O запускає набір n2o_mqtt воркерів — n2o_pi процесів, які слухають певні топіки певної кімнати. Відповіді надсилаються до теми подій, яка автоматичного підписана при старті сесії MQTT.

Лістинг 5. MQTT RPC Топіків
actions/:vsn/:module/:client events/:vsn/:node/:module/:client

RPC WebSocket

У випадку чистого WebSocket, в N2O реалізовано n2o_stream як cowboy модуль, що підтримує бінарні та текстові повідомлення.

Лістинг 6. Cowboy stream протокол
#binary { data :: binary() }. #text { data :: binary() }.

ПРИКЛАД

Нижче наведено приклад перевизначення INIT протоколу.

Лістинг 7. Користувацький протокол INIT
-module(custom_init). -include("n2o.hrl"). -export([info/3]). info({text,<<"N2O,",Pickle/binary>>}, Req, State) -> {'Token',Token} = n2o_session:authenticate([],Pickle), Sid = case n2o:depickle(Token) of {{S,_},_} -> S; X -> X end, New = State#cx{session = Sid}, {reply,{bert,{io,<<"console.log('connected')">>, {'Token',Token}}}, Req, New}; info(Message,Req,State) -> {unknown,Message,Req,State}.

НАЛАШТУВАННЯ

Просто допишіть ім'я модуля реалізації протоколу до значень ключа protocol в sys.config.

[{n2o,[{cache,n2o}, {upload,"priv/static"}, {mq,n2o_syn}, {ttl,900}, {timer,{0,1,0}} {tables,[cookies,file,caching,ring,async]}, {hmac,sha256}, {filename,n2o_ftp}, {formatter,n2o_bert}, {session,n2o_session}, {pickler,n2o_secret}, {protocols,[n2o_ftp,n2o_nitro]}, {nitro_prolongate,false}, {filter,{n2o_proto,push}}, {origin,<<"*">>}, {timer,{0,10,0}}]}].

N2O — це фасад для наступних сервісів: кеш, MQ, форматування повідомлень, сесії, кодування та циклів протоколів. Іншою частиною N2O є модуль n2o_pi, який запускає процеси додатку під наглядом, для можливості використання N2O API. В цій простій конфігурації ви можете встановити будь-яку реалізацію для будь-якого сервісу.

Наступні сервіси, наявні в модулі n2o, ви також можете довільно налаштовувати:

CACHE

Кеш — механізм зберігання в швидкій памяті. Просто зберігайте значення для ключів за допомогою наступних функцій, а системний таймер очищуватиме прострочені записи. Ви можете вибрати реалізацію модуля кешування, за допомогою параметру cache бібліотеки N2O. Реалізація n2o cache за замовчуванням являє собою ets з терміном зберігання записів.

cache(Tab, Key, Value, Till) -> term().

Записує значення Value із заданим TTL.

cache(Tab, Key) -> term().

Повертає значення по ключу Key.

MQ

Мінімальною вимогою до будь-якого фреймворка є наявність pub/sub API. N2O надає налаштовуваний API через параметр налаштувань mq.

reg(term()) -> term().

Підписати поточного клієнта на transient topic. У конкретних реалізаціях семантика може відрізнятись. В MQTT ви можете підписати оффлайн/онлайн клієнтів на будь-який персистентний топік. Також в MQTT ця функція підписує клієнта, а не Erlang процес.

unreg(term()) -> term().

Відписати поточного клієнта від перехідний топік. В MQTT ви можете видалити підписку з персистентної бази даних.

send(term(), term()) -> term().

Опублікувати повідомлення в топіку. В MQTT клієнти отримають повідомлення зі сховища ефірних транзакцій, як тільки появляться онлайн, у випадку, якщо на момент публікації повідомлення вони були оффлайн.

FORMAT

Ви вказуєте форматування в протоколі повернення повідомлення. Наприклад:

info({Code}, Req, State) -> {reply,{bert,{io,nitro:jse(Code),<<>>}}, Req, State};

encode(record()) -> binary().

Серіалізується з кортежа.

decode(binary()) -> record().

Серіалізується в кортеж.

Нижче приклад реалізації n2o_bert форматтера:

encode(Erl) -> term_to_binary(Erl). decode(Bin) -> binary_to_term(Bin,[safe]).

SESSION

Сесії зберігаються в issued tokens, закодовані з допомогою AES/CBC-128. За замовчуванням, всі значення сесії зберігаються у вигляду кешу в ETS, з реалізацією в n2o_session.

session(Key, Value) -> term().

Встановити значення змінної сессії.

Лістинг 8. Сесії
1> rr(n2o). [bin,client,cx,direct,ev,flush,ftp,ftpack,handler, mqtt_client,mqtt_message,pickle,server] 2> put(context,#cx{}). undefined 3> n2o:session(user,maxim). maxim 4> ets:tab2list(cookies). [{{[],user},{63710014344,"maxim"}}, {{<<"5842b7e749a8cf44c920">>,auth},{63710014069,[]}]

session(Key) -> term().

Отримати значення змінної сесії.

PICKLE

pickle(term()) -> binary().

Кодування Erlang терма.

depickle(binary()) -> term().

Декодування Erlang терма.

Цей модуль може бути пов'язаним з: n2o_pi, n2o_auth, n2o_stream, n2o_mqtt, n2o_proto.