[erlang-questions] ANN: ezwebframe - an easy web framework

Joe Armstrong erlang@REDACTED
Wed Dec 19 12:58:10 CET 2012


> On Wed, Dec 19, 2012 at 9:12 AM, Barco You <barcojie@REDACTED> wrote:
> Very nice idea.

> But how the browser understand the commands you send from erlang process?
for
> example here: {cmd, fill_div}

This is easy, here's an overview:

- Convert the Erlang command to JSON
- send the JSON on the websocket uing Erlang
- receive the JSON in Javascript
- parse the JSON
- build a Javascript command
- execute the Javascript command

Here are the details

0) assume there is a div xyz on the HTML page

   <div id="xyz"> ...</div>

1) We send a message to the browser:

Browser ! [{cmd,'fill_div'},{div,xyz},{txt,<<"<h1>Hello</h1>">>}]

This will fill the div with some HTML

2) The message [cmd,'fill_div'} ,,...] is converted to JSON
   and sent to the websocket:

This is done in lines 227-229 of
https://github.com/joearms/ezwebframe/blob/master/src/ezwebframe.erl

websocket_info([{cmd,_}|_]=L, Req, Pid) ->
    B = list_to_binary(encode([{struct,L}])),
    {reply, {text, B}, Req, Pid, hibernate};


Here's an example of encode in the Erlang shell:

> Cmd = [{cmd,fill_div},{id,xzy},{txt,<<"<h1>Hello</h1>">>}].
[{cmd,fill_div},{id,xyz},{txt,<<"<h1>Hello</h1>">>}]
> list_to_binary(ezwebframe_mochijson2:encode([{struct,Cmd}])).
<<"[{\"cmd\":\"fill_div\",\"id\":\"xyz\",\"txt\":\"<h1>Hello</h1>\"}]">>

This is a bit unreadable because the quotes are escaped: The JSON term
without escaping the quotes is:

[{"cmd":"fill_div","id":"xyz","txt":"<h1>Hello</h1>"}]

3) The client code has an event handler that is triggered when the
websocket receives data:

Line 37 of websock.js is

 websocket.onmessage = onMessage;

4) onMessage is defined like this:

function onMessage(evt) {
    var json = JSON.parse(evt.data);
    do_cmds(json);
}

function do_cmds(objs){
    // console.log('do_cmds', objs);
    for(var i = 0; i < objs.length; i++){
      var o = objs[i];
      // as a safety measure we only evaluate js that is loaded
      if(eval("typeof("+o.cmd+")") == "function"){
      eval(o.cmd + "(o)");
      } else {
        // console.log('bad_cmd', o);
        alert("bad_command:"+o.cmd);
      };
   };
}

The JSON command on the websocket is of the form

 [{cmd:Cmd, ...}]

After parsing with JSON.parse(evt.data) I can iterate over the commands
which are stored in an array objs[...]

The command I just send becomes the Javascript object

o = {cmd:fill_div, id:'xyz', txt:'<h1>Hello</h1>'}

I check that there really is a function called fill_div

with this

 if(eval("typeof("+o.cmd+")") == "function"){

and if there is I do this:

      eval(o.cmd + "(o)");

now o.cmd = 'fill_div' so this is equivalent to eval('fill_div(o)')

and so

fill_div(o) is called where

   o = {cmd:fill_div, id:'xyz', txt:'<h1>Hello</h1>'}

5) Finally fill_div is defined like this

(line 110 of
https://github.com/joearms/ezwebframe/blob/master/priv/websock.js)

function fill_div(o){
    $('#'+o.id).html(o.txt);
}

This method is easily extended.

Suppose Erlang sends a new command called color_page to change the
background color of the page

  Browser ! [{cmd,color_page},{color,<<"green">>}]

All you have to do is supply a javascript function called color_page:

  function color_page(o){
     document.body.style.backgroundColor=o.color;
  }


and make sure this gets loaded

Cheers

/Joe



Thants to say, you have to define all the commands and relevant parsing
> fucntions in a Javascript library?
>
> Thanks,
> Barco
>
> On Thu, Dec 13, 2012 at 6:17 PM, Joe Armstrong <erlang@REDACTED> wrote:
>
>> ezwebframe
>> ==========
>>
>> https://github.com/joearms/ezwebframe
>>
>> Pronounced "Easy web frame."
>>
>> About
>> =====
>>
>> Ezwebframe attempts to make web programming just a little bit easier.
>>
>> From Erlang point of view the browser *is* an Erlang process.
>>
>> Assume we have a web page populated with divs. For example:
>>
>>     <div id="a">
>>       ...
>>     </div>
>>
>>     <div id="b">
>>       ...
>>     </div>
>>
>> Erlang thinks the browser is a process. To fill div a with HTML an
>> Erlang process evaluates the command:
>>
>>      Browser ! [{cmd, fill_div}, {id, a}, {txt, B}]
>>
>> Where B is a binary containing HTML.
>>
>> In the browser controls can be programmed to send messages to Erlang,
>> for example, when we click on a button in the browser the Erlang
>> process controlling the window will be sent a message which can be
>> received with the statement:
>>
>>     receive
>>        {Browser, {struct, [{clicked, ButtonName}]}} ->
>>            ...
>>     end
>>
>> All this is achieved using a thin JSON layer over websockets and
>> with cowboy managing the websockets.
>>
>> Cheers
>>
>> /Joe
>>
>>
>>
>>
>>
>>
>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20121219/f2e528ba/attachment.htm>


More information about the erlang-questions mailing list