ПРЕРЕКВІЗИТИ
Для розгортання N2O SAMPLE вам знадобиться остання версія Ерланг
з пакетного менеджера вашої ОС. N2O SAMPLE сумісний з операційними
системами Ubuntu (apt), Windows (WSL), Android (termux),
та MacOS (brew), Arch (pacman).
$ sudo apt install erlang elixir build-essential cmake git
Оскільки філософія N2O мотивована мінімалізмом, природнім є використання
спартанського сетапу для розробника: ванільні редактори vim, emacs чи mc.
$ sudo apt emacs vim mc
ПРИКЛАДИ
Перша видання книги "N2O: No Bullshit Sane Framework for Wild Web" містила
лише ідіоматичний приклад [SAMPLE] використання Nitrogen веб-фреймворку.
КНИГА N2O (N2O BOOK Vol. 2) містить розширений набір
прикладів [CHAT,REST,REVIEW,SAMPLE,PLM,CRM] який демонструє
широкий спектр технічних засобів для автоматизації процесів на виробництві.
Також, перше видання книги містило приклади Erlang синтаксису у той час
як КНИГА N2O містить програми на мові Elixir. Незважаючи на це усі бібліотеки є
сумісними з обома мовами, а деякі приклади [CHAT,SAMPLE] реалізовані окремо
для двох мов одночасно, щоб користувачі могли порівняти синтаксис Erlang та Elixir.
Перевірка працездатності кожного прикладу здійснюється за допомогою mix :
$ mix deps.get
$ iex -S mix
CHAT
Використані бібліотеки:
[
{:cowboy, "~> 2.8"},
{:rocksdb, "~> 1.6.0"},
{:syn, "~> 2.1.1"},
{:n2o, "~> 8.8.1"},
{:kvs, "~> 8.10.4"}
]
Налаштування бібліотек N2O та KVS:
config :n2o,
port: 8042,
proto: CHAT.Server,
mqtt_services: [],
pickler: :n2o_secret,
mq: :n2o_syn,
upload: "./priv/static",
protocols: [:n2o_heart, CHAT.TXT]
config :kvs,
dba: :kvs_rocks,
dba_st: :kvs_st,
schema: [:kvs, :kvs_stream, CHAT]
Демонстрація використання:
$ wscat --no-check -c wss://localhost:8042/ws
> HELP
< N2O
| SEND
| BOX
| CUT .
> N2O maxim
< USER maxim
> SEND vlad HELO
< ERROR user doesn't exist.
> N2O vlad
< USER vlad
> SEND maxim OK
< NOTIFY vlad:maxim:1556151953113322286:OK
< ACK "1556151953113322286"
> N2O maxim
< USER maxim
> BOX
< LIST
vlad:maxim:1556151953113322286:OK
> SEND maxim this is me
< NOTIFY maxim:maxim:1556152151055371152:this is me
< ACK "1556152151055371152"
> SEND maxim back again
< NOTIFY maxim:maxim:1556152157283311935:back again
< ACK "1556152157283311935"
> BOX
< LIST
vlad:maxim:1556151953113322286:OK
maxim:maxim:1556152151055371152:this is me
maxim:maxim:1556152157283311935:back again
> CUT 1556152157283311935
< ERASED 3
> BOX
< LIST
>
SAMPLE
Використані бібліотеки:
[
{:cowboy, "~> 2.8.0"},
{:rocksdb, "~> 1.6.0"},
{:n2o, "~> 8.8.1"},
{:syn, "~> 2.1.1"},
{:kvs, "~> 8.10.4"},
{:nitro, "~> 6.11.4"},
]
Налаштування бібліотек N2O та KVS:
config :n2o,
port: 8002,
pickler: :n2o_secret,
mq: :n2o_syn,
upload: "./priv/static",
protocols: [:nitro_n2o, :n2o_ftp],
routes: Sample.Routes
config :kvs,
dba: :kvs_rocks,
dba_st: :kvs_st,
schema: [:kvs, :kvs_stream]
Демонстрація використання:
<main>
<form></form>
<textarea id="message" rows="4" autofocus="true"
placeholder="Just type what you think about this"></textarea>
<button id="upload">Browse</button>
<button id="send">chat</button>
<history id="history"></history>
</main>
У цьому прикладі наведена проста ініціалізація HTML контрольного
елементу постбеком login, в процесі якого (після натискання кнопки),
на сервер буде відправлений зміст контрольних елментів з іменами user
та room. На сервері реакція на цю подію буде у вигляді редіректу на
інший контролер сторінки index, з параметром кімнати room.
def event(:init) do
room = Sample.Application.room
KVS.ensure(writer(id: room))
N2O.reg({:topic, room})
N2O.reg(N2O.sid())
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]))
room
|> KVS.all()
|> Enum.each(fn {:msg, _, user, message} ->
event({:client, {user, message}})
end)
end
def event(:logout) do
N2O.user([])
NITRO.redirect("/app/login.htm")
end
def event(:chat) do
chat(NITRO.q(:message))
end
def event({:client, {user, message}}) do
NITRO.wire(jq(target: :message, method: [:focus, :select]))
NITRO.insert_top(:history, message(body: [author(body: user), NITRO.jse(message)]))
end
def chat(message) do
room = Sample.Application.room
user = N2O.user()
room
|> KVS.writer()
|> writer(args: {:msg, KVS.seq([], []), user, message})
|> KVS.add()
|> KVS.save()
N2O.send({:topic, room}, client(data: {user, message}))
end
$ open http://localhost:8001/app/index.htm
PLM
Використані бібліотеки:
[
{:kvs, "~> 6.7.7"},
{:n2o, "~> 6.8.1"},
{:nitro, "~> 4.7.7"},
{:cowboy, "~> 2.5.0"},
{:rocksdb, "~> 1.2.0"},
{:chat, "~> 3.8.1"},
{:syn, "~> 1.6.3"},
{:erp, "~> 0.7.17"},
{:bpe, "~> 4.7.5"},
{:form, "~> 4.7.0"}
]
Налаштування бібліотек N2O, KVS, FORM та SCHEMA:
config :n2o,
pickler: :n2o_secret,
mq: :n2o_syn,
port: 8043,
ttl: 60*3,
proto: CHAT.Server,
nitro_prolongate: true,
mqtt_services: [:erp, :plm],
ws_services: [:chat],
upload: "./priv/static",
protocols: [:n2o_heart, :n2o_nitro, CHAT.TXT, :n2o_ftp],
routes: PLM.Routes
config :schema,
boot: [:erp_boot, :plm_boot, :acc_boot, :pay_boot, :fin_boot]
config :kvs,
dba: :kvs_rocks,
dba_st: :kvs_st,
schema: [:kvs, :kvs_stream, :bpe_metainfo]
config :form,
registry: [
LDAP.Forms.Credentials,
LDAP.Forms.Access,
BPE.Forms.Create,
BPE.Rows.Trace,
BPE.Rows.Process,
FIN.Rows.Account,
FIN.Rows.Transaction,
PLM.Forms.Error,
PLM.Rows.Payment,
PLM.Rows.Investment,
PLM.Rows.Product
]
Демонстрація використання:
CRM
Використані бібліотеки:
[
{:elixir_make, "~> 0.6.0", runtime: false},
{:ex_doc, "~> 0.11", only: [:dev, :test]}
{:cowboy, "~> 2.9.0"},
{:cowlib, "~> 2.11.0"},
{:rocksdb, "~> 1.6.0"},
{:sax, "~> 1.0.0"},
{:ca, "~> 1.11.0"},
{:asic, "~> 0.4.1"},
{:barlix2, "~> 0.6.0"},
{:qrcode, "~> 0.1"},
{:n2o, "~> 8.12.1"},
{:soa, "~> 0.1.7"},
{:jsone, "~> 1.5.1"},
{:bpe, "~> 7.2.8"},
{:rpc, "~> 3.11.1"},
{:etop, "~> 0.7"},
{:kvs, "~> 8.12.0"},
{:smtp, "~> 1.1.2"},
{:koatuu, "~> 1.3.27"},
{:pop3, "~> 2.1.0"},
{:nitro, "~> 7.2.1"},
{:form, "~> 7.1.0"},
{:ecsv, "~> 1.4.2"},
]
Налаштування бібліотек N2O, KVS, BPE, FORM, SOA, SMTP та CRM:
config :bpe,
ttl: :infinity,
ping_discipline: :undefined,
timeout: 30000,
procmodules: [
:bpe_account,
NewInput.Proc,
NewOutput.Proc,
NewInternal.Proc,
NewResolution.Proc,
PeriodicResolution.Proc,
ReceiveSEV.Proc,
SendSEV.Proc
],
logger_level: :error,
logger: [
{:handler, :synrc, :logger_std_h,
%{
level: :debug,
id: :synrc,
max_size: 2000,
module: :logger_std_h,
config: %{type: :file, file: 'crm.log'},
formatter:
{:logger_formatter,
%{
template: [:time, ' ', :pid, ' ', :module, ' ', :msg, '\n'],
single_line: true
}}
}}
]
config :n2o,
pickler: AES.GCM,
mq: :n2o_syn,
port: 50111,
session: :n2o_session,
ttl: 60 * 60 * 8,
nitro_prolongate: false,
mqtt_host: [],
mqtt_tcp_port: 1883,
mqtt_services: [],
ws_services: [],
upload: "./priv/storage",
protocols: [:api_bpe, Elixir.CRM.Nitro, :api_ftp, :n2o_heart],
routes: CRM.Routes,
tables: [:cookies, :file, :web, :caching, :ws, :mqtt, :tcp,
:async, :track, :sev, :smtp, :pop3, :barqr, :cron,
:ftpSignature, :monitorChat]
config :crm,
onlyoffice_host: "mia.erp.uno",
active_org: 'MIA:DEMO',
active_edrpo: '34239034',
convert_server: "mia.erp.uno",
convert_dir: "qr-cache",
convert_ports: [2001, 2002, 2002, 2004],
production_convert: false,
sign_queue_length: 10,
sign_retry_count: 1,
barqr_queue_length: 4,
convert_queue_length: 4,
import_url: "http://0.0.0.0:0",
import_token: "password",
default_branch: '22222',
trusted_edrpo: ['34239034'],
trusted_sev: ['34239034'],
files_position: :top,
rules_module: CRM.RulesDemo,
deeds: "priv/import/demo/deeds_demo.csv",
org_name_short: "МІА: Демонстраційний",
any_auth_type: true,
test_org_allowed: true,
barcode_print_sticker: true,
barcode_print_doc: true,
boot: [:erp_boot, :acc_boot, :doc_boot, :data_boot, :crimes_boot,
CRIMES.BOOT.Docs, CRM.BOOT.Docs, CRM.BOOT.Forms, HELP.Index,
SEV.BOOT, CRM.BOOT.Templates, CRM.BOOT.HTML]
config :kvs,
dba: :kvs_rocks,
dba_st: :kvs_st,
schema: [:kvs, :kvs_stream, :bpe_metainfo, :erp, :crm]
config :form,
module: :form2,
registry: :"Elixir.CRM"
config :soa, :globals, version: "1.1"
config :smtp, smtp_opts: [[port: 2525]]