> 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><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">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">https://github.com/joearms/ezwebframe/blob/master/priv/websock.js</a>)<br>
<br>function fill_div(o){<br> $('#'+<a href="http://o.id">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<br><br>/Joe<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 class="h5">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 class="h5">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 class="im">_______________________________________________<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>