ELIXIR N2O MIX
Так, це вірно, ми випустили нову версію N2O для Elixir. Оскільки зараз червень, а N2O 6 років, це 6.6.6 :-) Загалом, це було вже так давно, що я відмовився від підтримки Elixir, задля того щоб мати змогу зосередитись на чомусь значущому, принаймні на стороні Erlang.
Під повною підтримкою N2O Elixir, я маю на увазі, автоматичний імпорт записів Erlang із використанням модуля та проксі-сервера, модифікування викликів із :n2o.sid() на N2O.sid(), тощо. Також, ми припускаємо, що mix.ex містить визначення точки входу програми та інші життєво важливі речі, але не більше! Оскільки N2O прийшов із країни підтримки чисті дупи, ми рекомендуємо лише життєво важливі макроси у верхній частині сторінки Sample.Index:
defmodule Sample.Index do
use N2O, with: [:kvx, :n2o, :nitro]
Мінімальний sys.config у Elixir config.exs синтаксисі матиме лише належне налаштування KVX для власного рівня DB (з використанням kvx_st як власної реалізації потокового серверу для RocksDB), протоколу NITRO та Sample.Routes.
config :n2o,
protocols: [:n2o_nitro],
routes: Sample.Routes
config :kvx,
dba: :kvx_rocks,
dba_st: :kvx_st,
schema: [:kvx,:kvx_stream]
Ми використовуємо простий бінарний шаблон як найшвидший спосіб маршрутизації, але ви можете використовувати будь-який код на цьому рівні:
defmodule Sample.Routes do
import N2O
def finish(state, cx), do: {:ok, state, cx}
def init(state, ctx) do
%{path: p} = cx(ctx,:req)
{:ok, state, cx(ctx, path: p, module: route_prefix(p))}
end
def route_prefix(<<"/ws/", p::binary>>), do: route(p)
def route_prefix(<<"/", p::binary>>), do: route(p)
def route_prefix(p), do: route(p)
def route(<<>>), do: Sample.Login
def route(<<"app/index", _::binary>>), do: Sample.Index
def route(<<"app/login", _::binary>>), do: Sample.Login
def route(_), do: Sample.Login
Фактична сторінка, яка містить пряме вбудовування N2O JavaScript SDK із CDN, наведена нижче та включена як статичний файл для ковбойського обслуговування (може також отримати з CDN):
HTML:
<header>
<h2 id=heading>room</h2>
<button id=logout>logout</button>
</header>
<main>
<form>
<textarea id=message rows='4'
autofocus placeholder="Just type what you think about this">
</textarea>
<button id=upload>Browse</button>
<button id=send>chat</button>
</form>
<history id="history">
</history>
</main>
JavaScript CDN ws.n2o.dev:
<script src='https://ws.n2o.dev/priv/utf8.js'></script>
<script src='https://ws.n2o.dev/priv/bert.js'></script>
<script src='https://ws.n2o.dev/priv/heart.js'></script>
<script src='https://ws.n2o.dev/priv/ieee754.js'></script>
<script src='https://ws.n2o.dev/priv/n2o.js'></script>
<script>host = location.hostname === 'sample.n2o.dev'
? 'ns.synrc.com' : location.hostname; port = 8001;</script>
<script src='https://ws.n2o.dev/priv/ftp.js'></script>
<script src='https://ws.n2o.dev/priv/nitro.js'></script>
<script>$io.do = function(r) { console.log(r); };</script>
<script>protos = [$bert]; N2O_start();</script>
INIT
Тут знаходиться код, який монтує події зворотного зв’язку JavaScript, що доставляє вихідну інформацію DOM на сервера. На сторінці підключення має бути надіслано маркер ініціалізації 'N2O', який викликає регістр :init case of event у модулі Sample.index
def event(:init) do
room = N2O.session(:room)
KVX.save(KVX.writer(NITRO.to_binary(room)))
N2O.reg({:topic,room})
N2O.reg(:n2o.sid())
NITRO.clear (:history)
NITRO.update(:upload, upload())
NITRO.update(:heading, h2(id: :heading, body: room))
NITRO.update(:logout, button(id: :logout,
postback: :logout, body: "Logout"))
NITRO.update(:send, button(id: :send, body: "Chat",
postback: :chat, source: [:message]))
Enum.each KVX.all(room), fn {:msg,_,u,m} -> event({:client,{u,m}}) end
end
Він містить ініціалізацію курсору KVX для цієї конкретної кімнати, а також продовжити підписку GPROC/SYN для двох тем: {:topic, room} і :n2o.sid() --- авторизований процес WebSocket. Зауважте, що у випадку оновлення елементів DOM вони вже повинні бути присутніми на сторінці, інакше ви отримаєте виняток помилки. У нижній частині події :init Nitrogen ви можете побачити отримання записаних повідомлень із бази даних. Усі вони передаються через подію {:client,_} event.
RENDER
def event({:client,{usr,msg}}) do
NITRO.wire(jq(target: :message,method: [:focus,:select]))
NITRO.insert_top(:history, message(body: [author(body: usr), msg]))
end
У цьому випадку він просто додає елемент DOM до :history div.
CHAT
Основною подією прикладного модуля Sample.Index є :chat. Він отримує імена кімнат і користувачів із сеансу та повідомлення з події, яка була надіслана клієнтом, потім зберігає їх у KVX і повідомляє про рендеринг.
def event(:chat) do
room = N2O.session(:room)
usr = N2O.user()
msg = NITRO.q(:message)
KVX.save(KVX.add(writer(KVX.writer(room),
args: {:msg,KVX.seq([],[]),usr,msg})))
N2O.send({:topic,room},client(data: {usr,msg}))
end

Наступна версія MAD зможе створити скелетний код Elixir. Джерела робочого SAMPLE портованого на Elixir, тут:
Brought to you by:
— am-kantox — Aleksei Matiushkin
— bushyn — Arseniy Bushyn
— lessless — Yevhenii Kurtov
— 5HT — Namdak Tonpa