Hi Joe,<div><br></div><div>Thank you very much for making a detailed illumination.</div><div><br></div><div>That is data structure determines algorithm -- what kind of data you put in the Json object determines what kind of action you make at client side. Very good.</div>
<div><br></div><div>Regards,</div><div>Barco<span></span><br><br>On Wednesday, December 19, 2012, Max Bourinov  wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Joe, thank you for great explanation!<br clear="all"><div><div><br></div><div>Max</div><br></div><br>
<br><br><div>On Wed, Dec 19, 2012 at 3:58 PM, Joe Armstrong <span dir="ltr"><<a>erlang@gmail.com</a>></span> wrote:<br><blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div>> On Wed, Dec 19, 2012 at 9:12 AM, Barco You <span dir="ltr"><<a>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><font color="#888888"></font></span></blockquote></div></blockquote></div>