index.tex 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. \section{N2O: Application Server}
  2. N2O was started as the first Erlang Web Framework
  3. that uses WebSocket protocol only. We saved great compatibility with Nitrogen
  4. and added many improvements, such as binary page construction,
  5. binary data transfer, minimized process spawns, transmission of all events over the WebSocket
  6. and work within Cowboy processes. N2O renders pages several times faster than Nitrogen.
  7. \subsection{Wide Coverage}
  8. N2O is unusual in that it solves problems in different web development domains
  9. and stays small and concise at the same time. Started as a Nitrogen concept
  10. of server-side framework it can also build offline client-side applications
  11. using the same source code. This became possible with powerful Erlang JavaScript Parse
  12. Transform which enables running Erlang on JavaScript platform and brings in Erlang and JavaScript
  13. interoperability. You can use Elixir, LFE and Joxa languages for backend development as well.
  14. \paragraph{}
  15. N2O supports DSL and HTML templates. It lets you build JavaScript
  16. control elements in Erlang and perform inline rendering with DSL using
  17. the same code base for both client and server-side.
  18. How to use N2O is up to you. You can build mobile applications using server-side rendering
  19. for both HTML and JavaScript thus reducing CPU cycles and saving the battery of a mobile device.
  20. Or you can create rich offline desktop applications using Erlang JavaScript compiler.
  21. \newpage
  22. \subsection*{Why Erlang in Web?}
  23. We have benchmarked all the existing modern web frameworks that were built using functional
  24. languages and Cowboy was still the winner. The chart below shows raw HTTP
  25. performance of functional and C-based languages with concurrent
  26. primitives (Go, D and Rust) on a VAIO Z notebook with i7640M processor.
  27. \includeimage{n2o_benchmark.png}{Web-Servers raw performance grand congregation}
  28. \paragraph{}
  29. Erlang was built for low latency streaming of binary data in telecom systems.
  30. It's fundamental design goal included high manageability, scalability
  31. and extreme concurrency. Thinking of WebSocket channels as binary
  32. telecom streams and web pages as user binary sessions
  33. helps to get an understanding reasons behind choosing Erlang
  34. over other alternatives for web development.
  35. \paragraph{}
  36. Using Erlang for web allows you to unleash the full power of telecom systems for
  37. building web-scale, event-driven, message-passing, NoSQL, asynchronous, non-blocking,
  38. reliable, highly-available, performant, secure, real-time, distributed applications.
  39. See Erlang: The Movie II.
  40. \paragraph{}
  41. N2O outperforms full Nitrogen stack with only 2X raw HTTP Cowboy
  42. performance downgrade thus upgrading rendering performance several
  43. times compared to any other functional web framework. And
  44. sure it's faster than raw HTTP performance of Node.js.
  45. \subsection{Rich and Lightweight Applications}
  46. There are two approaches for designing client/server communication.
  47. The first one is called 'data-on-wire'. With this approach only JSON, XML or binary
  48. data are transferred over RPC and REST channels. All HTML rendering
  49. is performed on the client-side. This is the most suitable approach for building desktop
  50. applications. Examples include React, Meteor and ClojureScript.
  51. This approach can also be used for building mobile clients.
  52. \paragraph{}
  53. Another approach is sending pre-rendered parts of pages and JS
  54. and then replacing HTML and executing JavaScript on the client-side. This approach
  55. is better suited for mobile web development since the
  56. client doesn't have much resources.
  57. \paragraph{}
  58. With N2O you can create both types of applications. You can use N2O REST framework
  59. for desktop applications based on Cowboy REST API along with DTL
  60. templates for initial HTML rendering for mobile applications.
  61. You can also use Nitrogen DSL-based approach for modeling parts of pages
  62. as widgets and control elements, thanks to Nitrogen
  63. rich collection of elements provided by Nitrogen community.
  64. \paragraph{}
  65. In cases when your system is built around Erlang infrastructure, N2O
  66. is the best choice for fast web prototyping, bringing simplicity
  67. of use and clean codebase. Despite HTML being transfered over the wire,
  68. you still have access to all your Erlang services directly.
  69. \paragraph{}
  70. You can also create offline applications using Erlang JavaScript compiler
  71. just the way you would use ClojureScript, Scala.js, Elm, WebSharper
  72. or any other similar tool. N2O includes: REST micro frameworks,
  73. server-side and client-side rendering engines,
  74. WebSocket events streaming, JavaScript generation
  75. and JavaScript macro system along with {\bf AVZ} authorization
  76. library (Facebook, Google, Twitter, Github, Microsoft), key-value storages
  77. access library {\bf KVS} and {\bf MQS} Message Bus client library (gproc, emqttd).
  78. \subsection{JSON and BERT}
  79. N2O uses JSON and BERT. All messages passed over
  80. WebSockets are encoded in native Erlang External Term Format.
  81. It is easy to parse it in JavaScript with {\bf dec(msg)}
  82. and it helps to avoid complexity on the server-side. Please refer
  83. to \footahref{http://bert-rpc.org}{http://bert-rpc.org} for detailed information.
  84. \subsection{DSL and Templates}
  85. We like Nitrogen for the simple and elegant way it constructs typed
  86. HTML with internal DSL. This is analogous to Scala Lift,
  87. OCaml Ocsigen and Haskell Blaze approach. It lets you develop reusable control
  88. elements and components in the host language.
  89. \paragraph{}
  90. Template-based approach (Yesod, ASP, PHP, JSP, Rails, Yaws and ChicagoBoss)
  91. requires developers to deal with raw HTML. It allows
  92. defining pages in terms of top-level controls, placeholders
  93. and panels. N2O also support this approach by proving bindings
  94. to DTL and ET template engines.
  95. \paragraph{}
  96. The main N2O advantage is its suitability for large-scale projects
  97. without sacrificing simplicity and comfort of prototyping solutions
  98. in fast and dynamic manner. Below is an example of complete Web Chat
  99. implementation using WebSockets that shows how Templates, DSL and
  100. asynchronous inter-process communication work in N2O.
  101. \newpage
  102. \vspace{1\baselineskip}
  103. \begin{lstlisting}[caption=chat.erl]
  104. -module(chat).
  105. -include_lib("nitro/include/nitro.hrl").
  106. -compile(export_all).
  107. main() ->
  108. #dtl { file = "login",
  109. app = review,
  110. bindings = [ { body, body() } ] }.
  111. body() ->
  112. [ #span { id=title, body="Your nickname: " },
  113. #textbox { id=user, body="Anonymous" },
  114. #panel { id=history },
  115. #textbox { id=message },
  116. #button { id=send, source=[user,message],
  117. body="Send",
  118. postback=chat } ].
  119. event(init) -> wf:reg(room), wf:async("looper",fun loop/1);
  120. event(chat) -> User = wf:q(user),
  121. Message = wf:q(message),
  122. n2o_async:send("looper",{chat,User,Message}).
  123. loop({chat,User,Message}) ->
  124. Terms = #panel { body = [
  125. #span { body = User }, ": ",
  126. #span { body = Message } ]},
  127. wf:insert_bottom(history, Terms),
  128. wf:flush(room).
  129. \end{lstlisting}
  130. \vspace{1\baselineskip}
  131. Just try to build the similar functionality with your favorite
  132. language/framework and feel the difference! Here are one message bus,
  133. one async {\bf gen\_server} worker under supervision, NITRO DSL, DTL template,
  134. WebSockets, HTML and JavaScript generation in a simple file that you can
  135. put in your N2O application directory tree without restart and
  136. manual compilation. Also you can create single-file bundle
  137. which is able to run in Windows, Linux and Mac. Moreover this
  138. application is ready to run under multiplatform LING Erlang virtual machine.
  139. \newpage
  140. \subsection*{Changes from Nitrogen}
  141. We took a liberty to break some compatibility with the original
  142. Nitrogen framework, mostly because we wanted to have a clean codebase
  143. and achieve better performance. However, it's still possible to port
  144. Nitrogen web sites to N2O quite easily. E.g., N2O returns id and
  145. class semantics of HTML and not {\bf html\_id}.
  146. We simplified HTML rendering without using
  147. {\bf html\_encode} which should be handled by application layer.
  148. \paragraph{}
  149. Nitrogen.js, originally created by Rusty Klophaus, was removed
  150. because of the pure WebSocket nature of N2O which doesn't
  151. require jQuery on the client-side anymore. In terms of lines of code
  152. we have impressive showing. New {\bf xhr.js} 25 LOC and {\bf bullet.js} 18 LOC
  153. was added as the replacement, also {\bf nitrogen.js} takes only 45 LOC.
  154. UTF-8 {\bf utf8.js} 38 LOC could be plugged separately only when you're
  155. using {\bf bert.js} 200 LOC formatter. {\bf n2o.js} protocol handler is about 20 LOC.
  156. \paragraph{}
  157. We also removed {\bf simple\_bridge} and optimized N2O on each level to
  158. unlock maximum performance and simplicity. We hope you will enjoy
  159. using N2O. We are fully convinced it is the most efficient way to
  160. build Web applications in Erlang.
  161. \paragraph{}
  162. Original Nitrogen was already tested in production under high load and we
  163. decided to remove {\bf nprocreg} process registry along
  164. with {\bf action\_comet} heavy process creation. N2O creates a single
  165. process for an async WebSocket handler, all operations
  166. are handled within Cowboy processes.
  167. \paragraph{}
  168. Also, we introduced new levels of abstraction. You can extend
  169. the set of available protocols (Nitrogen, Heartbeat, Binary),
  170. change protocol formatters to BERT, JSON or MessagePack, inject
  171. your code on almost any level. The code structure
  172. is clean and Nitrogen compatibility layer NITRO is fully detachable
  173. from N2O and lives in a separate {\bf synrc/nitro} application.