N2O is more that just web framework or even application server. It also has protocol specification that covers broad range of application domains. In this chapter we go deep inside network capabilities of N2O communications. N2O protocol also has an ASN.1 formal description, however here we will speak on it freely. Here is the landscape of N2O protocols stack.
Picture. Protocols Stack
You may find it similar to XML-based XMPP, binary COM/CORBA, JSON-based WAMP, Apache Camel or Microsoft WCF communication foundations. We took best from all and put into one protocols stack for web, social and enterprise domains providing stable and mature implementation for Erlang in a form of N2O application server.
N2O application server implemented to support N2O protocol definition in Erlang which is widely used in enterprise applications. Experimental implementation in Haskell n2o.hs exists which supports only core heart protocol along with bert formatter. We will show you how N2O clients are compatible across different server implementations in different languages.
For social connectivity one may need to use synrc/roster instant messaging server that supports roster protocol with variation for enabling public rooms muc or full-text search facilities.
There is no single system shipped to support all of N2O protocols but it could exist theoretically. For other protocols implementation you may refer to other products like spawnproc/bpe, synrc/rest or synrc/mq.
N2O protocol is formatter agnostic and it doesn’t strict you to use a particular encoder/decoder. Application developers could choose their own formatter per protocol.
E.g. N2O uses TEXT formatting for “PING” and “N2O,” protocol messages, across versions N2O used to have IO message formatted with JSON and BERT both. All other protocol messages were BERT from origin. Make sure formatters set for client and server is compatible.
Note that you may include to support more that one protocol on the client. At server side you can change formatter on the fly without breaking the channel stream. Each message during data stream could be formatted using only one protocol at a time. If you want to pass each message through more that one formatter you should write an echo protocol.
After message arrives to endpoint and handlers chain is being initializes, message then comes to protocol stack. N2O selects appropriative protocol module and handle the message. After than message is being formatted and replied back to stream channel. Note that protocol loop is applicable only to WebSocket stream channel endpoint.
Picture. Messaging Pipeline
Here is pseudocode how message travels for each protocol until some of them handle the message. Note tnat this logic is subject to change.
You may set up protocol from sys.config file, enabling or disabling some of them on the fly.
For example in Skyline (DSL) application you use only nitro protocol:
And in Games (SPA) application you need only spa protocol:
HEART protocol is essential WebSocket application level protocol for PING and N2O initialization. It pings every 4-5 seconds from client-side to server thus allowing to determine client online presence. On reconnection or initial connect client sends N2O init marker telling to server to reinitialize the context.
If pid field is not set in transition variable then you will request new session otherwise you may put here information from previously settled cookies for attaching to existing session. This pid disregarding set or empty will be bypassed as a parameter to N2O init marker.
You can manually invoke session initialization inside existing session:
In response on successful WebSocket connection and enabled heart protocol on the server you will receive the IO message event. IO events are containers for function and data which can be used as parameters. There is no predefined semantic to IO message. Second element of a tuple will be directly evaluated in WebBrowser. Third element can contain data or error as for SPA and BIN protocols, and can contain only error for NITRO protocol. IO events are not constructed on client. N2O request returns IO messages with evaluation string and empty data or empty evaluation string with error in data field.
You can try manually send this messag in web console to see whats happening, also you can enable logging the heartbeat protocol by including its module in log_modules:
Heartbeat protocol PING request returns PONG or empty NOP binary response.
NITRO protocol consist of three protocol messages: pickle, flush and direct. Pickled messages are used if you send messages over unencrypted channel and want to hide the content of the message, that was generated on server. You can use BASE64 pickling mechanisms with optional AES/RIPEMD160 encrypting. NITRO messages on success alway return empty data field in IO message and error otherwise. Here is definition to NITRO protocol in expect language:
Usually pickle events are being sent generated from server during rendering of nitro elements. To see how it looks like you can see inside IO messages returned from N2O initialization. There you can find something like this:
Invocation of pickle messages is binded to DOM elements using source and postback information from nitro elements.
Only fields listed in source will be included in pickle message on invocation. Information about module and event arguments (postback) is sent encrypted or pickled. So it would be hard to know the internal structure of server codebase for potential hacker. On the server you will recieve following structure:
You can depickle #ev event with wf:depickle API:
Information for #ev event is directly passed to page module as Module:event(Message) . Information from sources user and pass could be retrieved with wf:q API:
This is Nitrogen-based messaging model. Nitrogen WebSocket processes receive also flush and delivery protocol messages, but originated from server, which is internal NITRO protocol messages. All client requests originate IO message as a response.
Client messages usually originated at client and represent the Client API Requests:
Server messages are usually being sent to client originated on the server by sending info notifications directly to Web Socket process:
You can obtain this Pid during page init:
You can also send server messages from client relays and vice versa. It is up to your application and client/server handlers how to handle such messages.
When you need raw binary Blob on client-side, for images or other raw data, you can ask server like this:
Ensure you have defined #bin handler and page you are asking is visible by router:
Having enabled all loggin in module n2o_file, index and wf_convert you will see:
Or by adding handling for BIN protocol:
The formal description of BIN is simple relay: