Introduce N2O Protocols for commercial use on top of the MQTT protocol. Minimize and remove all features, overlapped with MQTT pub-sub broker. Provide an EMQ extension that immediately activates the N2O protocol and its applications for all connected MQTT devices. Create a single Erlang eco-system for Enterprise Protocol Federation and establish a solid CORBA/WS-SOAP/XMPP-replacement, ready for high-speed, low-latency IoT applications.

Web Framework w/o Web Server? Usually, Web Framework uses HTTP or WebSocket endpoints. But what if we need to connect application on devices with TCP/UDP transports? One of the protocols addressing this usecase is MQTT that was designed by Andy Stanford-Clark (IBM) and Arlen Nipper in 1999 for connecting Oil Pipeline telemetry systems over satellite. The protocol is designed to work over connectionless unreliable environments, and provides three levels of QoS delivery: at least once, at most once, exactly once. On the other hand, N2O is a federation of protocols, like XMPP/CORBA/WS. Although N2O supports several encoders (BERT/XML/JSON/TEXT) the extension to other channels beyond WebSockets would involve creating a new Socket Server. So we have decided to take MQTT as a transport/session protocol for N2O Federation. EMQ is an open-source MQTT broker implementation by Feng Lee. It's clean, concise and robust. We've developed an EMQ compatible plugin that works entirely within MQTT sessions just like N2O already does within Cowboy's ranch sessions. This is the main difference from Phoenix's gen_server channels. Picture 1. Protocol Modules Picture 2. Protocol Messages

N2O: Protocol Server for MQTT Starting from 4.5, N2O reduce everything duplicating MQTT features. On the other hand, 4.5 is a completely N2O-compatible embeddable protocol relay with limited features. And it takes only 25KB in Erlang. n2o — N2O Protocol Server version 4.5 MQTT — 10KB

— N2O Protocol Server version 4.5 MQTT — 10KB n2o_async — N2O Async Streams: gen_server — 4KB

— N2O Async Streams: gen_server — 4KB n2o_format — N2O Formatter: JSON, BERT — 2KB

— N2O Formatter: JSON, BERT — 2KB n2o_ftp — N2O File Protocol: FTP — 4KB

— N2O File Protocol: FTP — 4KB n2o_nitro — N2O Nitro Protocol: PICKLE, FLUSH, DIRECT, IO, INIT — 3KB

— N2O Nitro Protocol: PICKLE, FLUSH, DIRECT, IO, INIT — 3KB n2o_proto — N2O Protocols Loop: NITRO, FTP — 1KB

— N2O Protocols Loop: NITRO, FTP — 1KB n2o_secret — N2O Security: HMAC AES/CBC-128 — 1KB N2O 4.5 provides real smooth experience for developers: clean git history, small codebase, nitro compatible, man/html docs. Listing 1. N2O 4.5 MQTT $ time git clone git://github.com/synrc/mqtt real 0m0.794s $ cloc . 370 $ cat rebar.config {deps, [{nitro, "git://github.com/synrc/nitro"}, {n2o, "git://github.com/synrc/mqtt"}]}. $ man ./man/n2o.1

N2O things deprecated due to MQTT N2O_start and n2o.js are no longer used in MQTT version of N2O. Instead of N2O_start, MQTT_start and mqtt.js should be used for session control replacement. We traded HEART protocol and session facilities for built-in MQTT features. N2O authentication and authorization mechanisms are also abandoned as MQTT could provide AUTH features too. Obviously wf:reg and wf:send APIs have also been abandoned as we can use emqttd API directly and {deliver,_} protocol of ws_client gen_server. n2o_session — no Browser, so no Cookies are needed

— no Browser, so no Cookies are needed n2o_stream — no XHR fallback needed

— no XHR fallback needed n2o_heart — no PING protocol needed

— no PING protocol needed n2o_mq — syn and gproc are no longer needed

— syn and gproc are no longer needed n2o_query — no Query Router

— no Query Router N2O_start — replaced by MQTT_start

— replaced by MQTT_start ranch — replaced with esockd

— replaced with esockd cowboy — replaced with mochiweb for WebSocket endpoint N2O.PDF

Endpoints All N2O/MQTT messages which go directly to TCP and/or WebSocket. However there are some endpoints which are not TCP sockets, even non-sockets, like gen_server endpoint, HTTP REST endpoint, which is non-WebSocket endpoint, and there is a room for other endpoint types. Here is a list of types of endpoints which are supported by EMQ and accesible to N2O apps: WebSockets, MQTT, MQTT-SN, TCP, UDP, CoAP. Normal use of N2O as a Web Framework or a Web Application Server is through WebSockets, but for IoT and MQTT applications it could be served through UDP or SCTP protocols providing application level message delivery consistency. By using MQTT as a transport we extend the supported set of endpoint protocols. Also N2O is able to work under cowboy Erlang web server and mochiweb web server. There is rest library to deal with REST endpoint.

MQTT Sessions N2O is working entirely in the context of ws_client processes of EMQ, just as it is working on top of ranch processes of cowboy. No additional gen_server is being introduced. The only official transparent way with zero abstraction is to use EMQ hooks mechanism. For N2O we need to implement only two cases: client.subscribe and message.delivered. On client.subscribe we deliver all persistent data that are ready for the client. On message.delivered we unpack any N2O BERT protocol message inside MQTT session.

N2O and MQTT Formatters N2O supports TEXT, JSON, XML, BERT, MessagePack formatters but you can add your own implementations either. They are terminal formatters before socket interface library (usually ranch or esockd). For example one may format IO message with BERT encoding n2o:format({io,Eval,Data},bert). MQTT format messages only in MQTT format. You can wrap binary B in MQTT packet as emqttd_message:make(Name, 0, Name, B).

Sample Application Listing 2. Sample Web Application written in NITRO DSL main() -> []. event(init) -> nitro:update(loginButton, #button{id=loginButton,body="Login", postback=login,source=[user,pass]}); event(login) -> nitro:redirect("index.htm?room=" ++ nitro:to_list( n2o:q(pass))); Picture 3. N2O Review Application

EMQ Plugin Implementation Here you will see the implementation of N2O bridge for EMQ. We will inject N2O loop inside EMQ session handlers. As you may know, the single point of entrance in N2O is the event(init) message handler. It can only be reached by calling {init,_} message of NITRO protocol. Listing 3. Emulating "N2O," init handshake on_client_subscribe(ClientId, Username, TopicTable, _Env) -> Name = binary_to_list(iolist_to_binary(ClientId)), BinTopic = element(1,hd(TopicTable)), put(topic,BinTopic), n2o_cx:context(#cx{module=route:select(BinTopic), formatter=bert,params=[]}), case n2o_proto:info({init,<<>>},[],?CTX) of {reply, {binary, M}, _, #cx{}} -> self() ! {deliver, emqttd_message:make(Name, 0, Name, M)}; _ -> skip end, {ok, TopicTable}. However N2O MQTT is a protocol federation so we need to handle not only N2O messages, but also KVS, ROSTER, BPE, REST protocols. Thus after initialization during client.subscribe we call n2o_proto:info — the entire N2O protocol chain recursor inside message.delivered hook. This is the best place to put the federation relay for N2O modules. Listing 4. Emulating N2O message delivery on_message_delivered(ClientId, Username, Message = #mqtt_message{topic = Topic, payload = Payload}, _Env) -> Name = binary_to_list(ClientId), case n2o_proto:info(binary_to_term(Payload),[],?CTX) of {reply, {binary, M}, R, #cx{}} -> case binary_to_term(M) of {io,X,_} -> Msg = emqttd_message:make(Name, 0, Name, M), self() ! {deliver, Msg}, {ok, Message}; _ -> {ok, Message} end; _ -> {ok, Message} end.

MQTT JavaScript Client Listing 5. mq.js var topic = module + "_" + params.room || "lobby", mqtt = new Paho.MQTT.Client("127.0.0.1", 8083, ''), subscribeOptions = { qos: 0, onSuccess: function () { console.log("N2O Subscribed"); }, onFailure: function (m) { console.log("SUB Failure: " + message.errorMessage); }, timeout: 3 }, options = { timeout: 3, onFailure: function (m) { console.log("SND Failure: " + m.errorMessage); }, onSuccess: function () { console.log("N2O Connected"); mqtt.subscribe(topic, subscribeOptions); } }, ws = { send: function (payload) { var message = new Paho.MQTT.Message(payload); message.destinationName = topic; message.qos = 0; mqtt.send(message); } }; function MQTT_start() { mqtt.onConnectionLost = function (o) { }; mqtt.onMessageArrived = function (m) { var BERT = m.payloadBytes.buffer.slice( m.payloadBytes.byteOffset, m.payloadBytes.byteOffset + m.payloadBytes.length); try { erlang = dec(BERT); console.log(utf8_dec(erlang.v[1].v)); for (var i=0;i

Enable EMQ Plugin The N2O over MQTT bridge is a drop-in plugin for EMQ broker. After starting the server you should enable N2O over MQTT bridge EMQ plugin on plugin page http://127.0.0.1:18083/#/plugins and then open the application sample http://127.0.0.1:8000/spa/login.htm Picture 4. N2O 4.5 MQTT as EMQ Plugin The nice thing about EMQ is that it enables session introspection for N2O connections. The EMQ Dashboards is written in vue.js and a bit complex for admin application. The possible and expecting hackaton is on rewriting EMQ admin with hyperapp and n2o. The IBM library Paho is also too old and fat to fit N2O sizes. Some parts should be replaced with more modern and compact pinger and connection respawning from n2o.js. This is expecting further research and imporevement. Picture 5. Inspecting N2O sessions with EMQ