Joe, thank you for great explanation!<br clear="all"><div><div><br></div><div>Max</div><br></div><br>
<br><br><div class="gmail_quote">On Wed, Dec 19, 2012 at 3:58 PM, Joe Armstrong <span dir="ltr"><<a href="mailto:erlang@gmail.com" target="_blank">erlang@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">> On Wed, Dec 19, 2012 at 9:12 AM, Barco You <span dir="ltr"><<a href="mailto:barcojie@gmail.com" target="_blank">barcojie@gmail.com</a>></span> wrote:<br>> Very nice idea.<div><br></div><div>
> But how the browser understand the commands you send from erlang process? for <br>

> example here: {cmd, fill_div}</div></div><div><br>This is easy, here's an overview:<br><br>- Convert the Erlang command to JSON<br></div>- send the JSON on the websocket uing Erlang<br>- receive the JSON in Javascript<br>


- parse the JSON<br>- build a Javascript command<br>- execute the Javascript command<br><br>Here are the details<br><br>0) assume there is a div xyz on the HTML page<br><br>   <div id="xyz"> ...</div><br>


<br>1) We send a message to the browser:<br><br>Browser ! [{cmd,'fill_div'},{div,xyz},{txt,<<"<h1>Hello</h1>">>}]<br><br>This will fill the div with some HTML<br><br>2) The message [cmd,'fill_div'} ,,...] is converted to JSON<br>


   and sent to the websocket:<br><br>This is done in lines 227-229 of <br><a href="https://github.com/joearms/ezwebframe/blob/master/src/ezwebframe.erl" target="_blank">https://github.com/joearms/ezwebframe/blob/master/src/ezwebframe.erl</a><br>


<br>websocket_info([{cmd,_}|_]=L, Req, Pid) -><br>    B = list_to_binary(encode([{struct,L}])),<br>    {reply, {text, B}, Req, Pid, hibernate};<br><br><br>Here's an example of encode in the Erlang shell:<br><br>> Cmd = [{cmd,fill_div},{id,xzy},{txt,<<"<h1>Hello</h1>">>}].<br>


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


<br>This is a bit unreadable because the quotes are escaped: The JSON term<br>without escaping the quotes is:<br><br>[{"cmd":"fill_div","id":"xyz","txt":"<h1>Hello</h1>"}]<br>


<br>3) The client code has an event handler that is triggered when the<br>websocket receives data:<br><br>Line 37 of websock.js is<br><br> websocket.onmessage = onMessage; <br><br>4) onMessage is defined like this:<br><br>


function onMessage(evt) {<br>    var json = JSON.parse(evt.data);<br>    do_cmds(json);<br>}<br><br>function do_cmds(objs){<br>    // console.log('do_cmds', objs);<br>    for(var i = 0; i < objs.length; i++){<br>


      var o = objs[i];<br>      // as a safety measure we only evaluate js that is loaded<br>      if(eval("typeof("+o.cmd+")") == "function"){<br>      eval(o.cmd + "(o)");<br>      } else {<br>


        // console.log('bad_cmd', o);<br>        alert("bad_command:"+o.cmd);<br>      };<br>   };<br>}<br><br>The JSON command on the websocket is of the form<br><br> [{cmd:Cmd, ...}]<br><br>After parsing with JSON.parse(evt.data) I can iterate over the commands <br>


which are stored in an array objs[...]<br><br>The command I just send becomes the Javascript object<br><br>o = {cmd:fill_div, id:'xyz', txt:'<h1>Hello</h1>'}<br><br>I check that there really is a function called fill_div<br>


<br>with this<br><br> if(eval("typeof("+o.cmd+")") == "function"){<br><br>and if there is I do this:<br><br>      eval(o.cmd + "(o)");<br><br>now o.cmd = 'fill_div' so this is equivalent to eval('fill_div(o)')<br>


<br>and so<br><br>fill_div(o) is called where <br><br>   o = {cmd:fill_div, id:'xyz', txt:'<h1>Hello</h1>'}<br><br>5) Finally fill_div is defined like this<br><br>(line 110 of <a href="https://github.com/joearms/ezwebframe/blob/master/priv/websock.js" target="_blank">https://github.com/joearms/ezwebframe/blob/master/priv/websock.js</a>)<br>


<br>function fill_div(o){<br>    $('#'+<a href="http://o.id" target="_blank">o.id</a>).html(o.txt);<br>}<br><br>This method is easily extended.<br><br>Suppose Erlang sends a new command called color_page to change the<br>

background color of the page<br>
<br>  Browser ! [{cmd,color_page},{color,<<"green">>}]<br><br>All you have to do is supply a javascript function called color_page:<br><br>  function color_page(o){<br>     document.body.style.backgroundColor=o.color;<br>


  }<br><br><br>and make sure this gets loaded<br><br>Cheers<span class="HOEnZb"><font color="#888888"><br><br>/Joe</font></span><div class="HOEnZb"><div class="h5"><br><br><br><div class="gmail_quote"><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div>Thants to say, you have to define all the commands and relevant parsing fucntions in a Javascript library?</div>

<div><br></div><div>Thanks,</div><div>Barco<br><br><div class="gmail_quote"><div><div>On Thu, Dec 13, 2012 at 6:17 PM, Joe Armstrong <span dir="ltr"><<a href="mailto:erlang@gmail.com" target="_blank">erlang@gmail.com</a>></span> wrote:<br>



</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>ezwebframe<br>==========<br><br><a href="https://github.com/joearms/ezwebframe" target="_blank">https://github.com/joearms/ezwebframe</a><br>



<br>Pronounced "Easy web frame."<br><br>About<br>=====<br><br>Ezwebframe attempts to make web programming just a little bit easier.<br>
<br>From Erlang point of view the browser *is* an Erlang process.<br><br>Assume we have a web page populated with divs. For example:<br><br>    <div id="a"><br>      ...<br>    </div><br><br>    <div id="b"><br>




      ...<br>    </div><br><br>Erlang thinks the browser is a process. To fill div a with HTML an <br>Erlang process evaluates the command:<br><br>     Browser ! [{cmd, fill_div}, {id, a}, {txt, B}]<br><br>Where B is a binary containing HTML.<br>




<br>In the browser controls can be programmed to send messages to Erlang,<br>for example, when we click on a button in the browser the Erlang<br>process controlling the window will be sent a message which can be<br>received with the statement:<br>




<br>    receive<br>       {Browser, {struct, [{clicked, ButtonName}]}} -><br>           ...<br>    end<br><br>All this is achieved using a thin JSON layer over websockets and<br>with cowboy managing the websockets.<br>




<br>Cheers<span><font color="#888888"><br><br>/Joe<br><br><br><br> <br><br><br><br>
</font></span><br></div></div><div>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></div></blockquote></div><br></div>
</blockquote></div><br>
</div></div><br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></blockquote></div><br>