Home > misc > WebSocket 和 Erlang

WebSocket 和 Erlang

December 11th, 2009 :: jackyz

好久没有露面的 Joe 大爷又在 Maillist 里出现了。这一次,他老人家在自己的 Google Chrome 浏览器上体验了一把 HTML5 的核心特性 —— 顺手用寥寥数十行的 Erlang 代码捣鼓出来了一个 WebSocket 服务器的参考实现(围观群众起哄:胜之不武,这本来就是 Erlang 的拿手好戏嘛)。咱还是照旧,废话少说,先上代码:

  1. <body>
  2. <script>
  3.    alert("hello");
  4.    if ("WebSocket" in window) {
  5.        var ws = new WebSocket("ws://localhost:1234");
  6.        ws.onopen = function() {
  7.            // Web Socket is connected. You can send data by send() method.
  8.            ws.send("hello from the browser");
  9.        };
  10.        ws.onmessage = function (evt) {
  11.                var data = evt.data; alert(data);
  12.        };
  13.        ws.onclose = function() {
  14.                alert("closed");
  15.        };
  16.    } else {
  17.        alert("sad");
  18.    };
  19. </script>
  20. </body>
  1. -module(local_server).
  2. -compile(export_all).
  3.  
  4. start() ->
  5.    {ok, Listen} = gen_tcp:listen(1234, [{packet,0},
  6.                                         {reuseaddr,true},
  7.                                         {active, true}]),
  8.    spawn(fun() -> par_connect(Listen) end).
  9.  
  10. par_connect(Listen) ->
  11.    {ok, Socket} = gen_tcp:accept(Listen),
  12.    spawn(fun() -> par_connect(Listen) end),
  13.    wait(Socket).
  14.  
  15. wait(Socket) ->
  16.    receive
  17.        {tcp, Socket, Data} ->
  18.            io:format("received:~p~n",[Data]),
  19.            Msg = prefix() ++
  20.                "WebSocket-Origin: http://localhost:2246\r\n" ++
  21.                "WebSocket-Location: ws://localhost:1234/\r\n\r\n",
  22.            gen_tcp:send(Socket, Msg),
  23.            loop(Socket);
  24.        Any ->
  25.            io:format("Received:~p~n",[Any]),
  26.            wait(Socket)
  27.    end.
  28.  
  29. prefix() ->
  30.    "HTTP/1.1 101 Web Socket Protocol Handshake\r\nUpgrade:
  31. WebSocket\r\nConnection: Upgrade\r\n".
  32.  
  33. loop(Socket) ->
  34.    receive
  35.        {tcp, Socket, Data} ->
  36.            Data1 = unframe(Data),
  37.            io:format("received:~p~n",[Data1]),
  38.            gen_tcp:send(Socket, [0] ++ "hello from erlang" ++ [255]),
  39.            loop(Socket);
  40.        Any ->
  41.            io:format("Received:~p~n",[Any]),
  42.            loop(Socket)
  43.    end.
  44.  
  45. unframe([0|T]) -> unframe1(T).
  46.  
  47. unframe1([255]) -> [];
  48. unframe1([H|T]) -> [H|unframe1(T)].

技术的部分已经说完了,就象 Joe 老头的那 48 行代码那样——简单明了,连注释都不需要。下面借 Joe 老头的光,顺便 Blah 一下。

Joe 老头说:

But I think it will kill ajax and comet and all that crap. Ajax is painful if you only want to send very small amounts of data, you still have to spend all your time parsing the http headers. Comet and long-poll etc will die since they are totally unecessary.

What I hope will happen that Google will pre-empt some action in firefox and this will push Microsoft into action – I can’t understand why this has taken so long after all it’s merely a question of *removing* code from the browser and giving access to the low-level socket interface.

It will make applications symmetric – anything that involved pushing data to the client was tricky hence the horrific workarounds that comet and long-poll involved – now things like chat in the browser become symmetric push/pull applications.

About time say I – I’ve waited years for this.

见过我的同学都知道,我关注这个领域(Ajax -> Erlang)有日子了,一直都在各种场合大肆吹嘘 Erlang 和 Ajax 是“天生的一对”。因此,大概也可以冒充半块砖(家)吧,老实说,对于 WebSocket 我也很兴奋,但对于它的前景我却不象 Joe 老头一样乐观。

从技术角度,不难预见 WebSocket 的普及将会带来 Web 应用领域的另外一场巨变。为了适应这一“气候变化”,现有的“技术物种”(框架怪兽和模式恐龙)必将再次剧烈进化,灭绝掉其中的几种也大有可能(其中之一就是现在的 OS 将会被“边缘化”)。然后,当当当,新的 Web 和一大堆新名词又将“横空出世”。但,就目前而言,这场变革还没有大幕拉开的迹象(至少远比我们这些观察家期望的要慢得多)。这无关技术,听起来好像很阴谋论,但这确实更像是一场智谋的较量。

多年以来,邪恶的 M$ 先通过免费和 OS 绑定来占领市场,然后通过有预谋的 IE 不作为,使得浏览器市场出现了畸形的“安定团结”局面。这些长期“被河蟹”的绑定用户,他们开始觉得浏览器就应该是这样缓慢、不安全、而且功能受限的。他们这群人,既是变革的最大受益者,但与此同时,却也正是这一变革当前最大的障碍,具有讽刺意味吧(历史何其相似)。

然而,第一个可以体验 WebSocket 的 Google Chrome 却并非第一个实现这一特性的浏览器。FireFox 早就已经实现了,然而这个特性却一直停留在 trunk 之中(有好奇心的童鞋可以看这里顺便练练英文),尘封已久。作为旗手兼宣传队和播种机的 Google Chrome 是第一个把 WebSocket 拿出来 show 的。记得当初 Google Chrome 计划推出时不少人还有疑惑——“为什么不直接加入OpenSource 的 Firefox 项目呢?”,现在回想起来,是不是有点豁然开朗的意思?

窑洞的墙壁上挂着一张巨大的世界地图,Google 主教和 M$ 长老分别站在地图前的左右两侧,叉着腰、拿着红蓝铅笔,做沉思装……。

又到了万众期待的押宝时刻,想冒一把险,给自己整个“xx框架创始人”头衔的同学,赶紧了。

misc

  1. Jer
    December 11th, 2009 at 17:50 | #1

    :D
    拭目以待

  2. Aeolus
    December 12th, 2009 at 05:44 | #2

    昨天见了Joe本人,很大师级别。老人家还演示来些有趣的东西, irc among applicaion 中间提到了chrome, 很童真的想法。

  3. Tea
    December 23rd, 2009 at 23:15 | #3

    弱弱的问一句,谁试过他老人家的代码吗。。。我怎么在握手阶段就卡住了。。。

  4. Tea
    December 24th, 2009 at 19:01 | #4

    老头子握手那段写错了。。。郁闷,研究了一个晚上。

    WebSocket-Origin: http://localhost:2246\r\n
    WebSocket-Location: ws://localhost:1234/\r\n\

    这两个字段应该改成这样:
    WebSocket-Location: ws://127.0.0.1:1234/\r\n
    WebSocket-Origin: http://127.0.0.1\r\n

    然后握手才能成功。

  5. December 30th, 2009 at 12:00 | #5

    “…对于 WebSocket 我也很兴奋,但对于它的前景我却不象 Joe 老头一样乐观。…”
    恩.同意.其实这个不单纯是技术问题, 涉及到商业利益.

    在我blog里推荐并顺便评论下了哦…
    http://hi.baidu.com/yarcowang/blog/item/bb570efbc1e69615a8d311bf.html

  6. soul
    January 6th, 2010 at 23:02 | #6

    Tea :
    弱弱的问一句,谁试过他老人家的代码吗。。。我怎么在握手阶段就卡住了。。。

    用的是ChromePlus吧

  7. rain2005
    January 16th, 2010 at 17:04 | #7

    很有意义的东东哦,但是前景有时与技术无关哦。

  8. January 27th, 2010 at 14:36 | #8

    misultin 已经支持websocket了…

  9. 123321
    March 9th, 2010 at 13:28 | #9

    Tea :老头子握手那段写错了。。。郁闷,研究了一个晚上。
    WebSocket-Origin: http://localhost:2246\r\nWebSocket-Location: ws://localhost:1234/\r\n\
    这两个字段应该改成这样:WebSocket-Location: ws://127.0.0.1:1234/\r\nWebSocket-Origin: http://127.0.0.1\r\n
    然后握手才能成功。

    没有写错,只不过服务器地址要和你的实际情况吻合才能握手成功。

  10. ccokme
    March 23rd, 2010 at 10:35 | #10

    @Tea
    试过了,没问题

  11. 美洲豹
    March 25th, 2010 at 16:39 | #11

    弱弱的问一句,WebSocket 支持二进制传输部

  12. CYF
    May 10th, 2010 at 14:42 | #12

    本人比较背,一直这样:
    received:”GET / HTTP/1.1\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nHost: localhost:1234\r\nOrigin: http://localhost:8061\r\n\r\n”
    Received:{tcp_closed,#Port}
    不知是否和Win2003有关系。

  13. cat
    June 25th, 2010 at 13:12 | #13

    @CYF
    看起来确实跟2003有关系,在xp上都没问题

  1. No trackbacks yet.