[erlang-questions] web sockets almost working ....

Joe Armstrong <>
Thu Dec 10 14:32:23 CET 2009


On Thu, Dec 10, 2009 at 2:19 PM, Jayson Vantuyl <> wrote:
> I don't know if I'd call that an AJAX killer just yet.  Particularly, until IE has a usable implementation.

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.

/Joe


>
> Also, I find this to be a really odd spec, because the "bytes" part is not "bytes", but it's supposed to be UTF-8.  It seems odd to use binary framing around UTF-8 with something that looks like a web connection and runs over the same ports as HTTP.  It looks to me like AJAX isn't dying, but rather HTTP.  After all, I can't imagine why they would pick UTF-8 unless they wanted to encode header-style data or, surprise, XML!  Even the framing is unfriendly to full, binary protocols.
>
> I, personally, would have preferred an actual framed, byte-level protocol over HTTP-lite.  :(

Yup - they could have sent a variable length header, containing the
length length (N) followed by N bytes - but that would be too easy ...

>
> On Dec 10, 2009, at 4:56 AM, Joe Armstrong wrote:
>
>> Thanks now it works beautifully, I've enclosed listings below.
>>
>> First reflection - this is amazing - the overhead is tiny and there is
>> no parsing
>> headers etc. The erlang just had to send
>>
>> [0] ... bytes .. [255] and it ended up in the browser.
>>
>> This will kill Ajax, keep-alive connections etc, now all google has to
>> do is ship
>> the parse trees of HTML pages instead of *text* and browsers can skip parsing
>> and concentrate on rendering and stuff will go fast ...
>>
>> Now somebody just has to be the first to implement
>> http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-65
>> in Erlang
>>
>> /Joe
>>
>> The web page is now:
>>
>>
>> <body>
>>  <script>
>>    alert("hello");
>>    if ("WebSocket" in window) {
>>       var ws = new WebSocket("ws://localhost:1234");
>>
>>       ws.onopen = function() {
>>           // Web Socket is connected. You can send data by send() method.
>>           ws.send("hello from the browser");
>>       };
>>
>>       ws.onmessage = function (evt)
>>           {
>>               var data = evt.data; alert(data);
>>           };
>>
>>       ws.onclose = function()
>>           {
>>               alert("closed");
>>           };
>>    } else {
>>       alert("sad");
>>    };
>>
>>  </script>
>> </body>
>>
>> And the erlang is:
>>
>> -module(local_server).
>> -compile(export_all).
>>
>> start() ->
>>    {ok, Listen} = gen_tcp:listen(1234, [{packet,0},
>>                                        {reuseaddr,true},
>>                                        {active, true}]),
>>    spawn(fun() -> par_connect(Listen) end).
>>
>> par_connect(Listen) ->
>>    {ok, Socket} = gen_tcp:accept(Listen),
>>    spawn(fun() -> par_connect(Listen) end),
>>    wait(Socket).
>>
>> wait(Socket) ->
>>    receive
>>       {tcp, Socket, Data} ->
>>           io:format("received:~p~n",[Data]),
>>           Msg = prefix() ++
>>               "WebSocket-Origin: http://localhost:2246\r\n" ++
>>               "WebSocket-Location: ws://localhost:1234/\r\n\r\n",
>>           gen_tcp:send(Socket, Msg),
>>           loop(Socket);
>>       Any ->
>>           io:format("Received:~p~n",[Any]),
>>           wait(Socket)
>>    end.
>>
>> prefix() ->
>>    "HTTP/1.1 101 Web Socket Protocol Handshake\r\nUpgrade:
>> WebSocket\r\nConnection: Upgrade\r\n".
>>
>> loop(Socket) ->
>>    receive
>>       {tcp, Socket, Data} ->
>>           Data1 = unframe(Data),
>>           io:format("received:~p~n",[Data1]),
>>           gen_tcp:send(Socket, [0] ++ "hello from erlang" ++ [255]),
>>           loop(Socket);
>>       Any ->
>>           io:format("Received:~p~n",[Any]),
>>           loop(Socket)
>>    end.
>>
>> unframe([0|T]) -> unframe1(T).
>>
>> unframe1([255]) -> [];
>> unframe1([H|T]) -> [H|unframe1(T)].
>>
>>
>>
>>
>> On Thu, Dec 10, 2009 at 1:34 PM, Colm Dougan <> wrote:
>>> Joe,
>>>
>>> On Thu, Dec 10, 2009 at 10:21 AM, Joe Armstrong <> wrote:
>>>> Very exciting - web sockets is partially working - this is very very
>>>> very exciting
>>>>
>>>> But I can't get past the handshake ...
>>>
>>> It appears to make a difference if you add a trailing slash after
>>> WebSocket-Location, i.e. :
>>>
>>>   "WebSocket-Location: ws://localhost:1234/\r\n\r\n",
>>>
>>> Now I get :
>>>
>>> Eshell V5.7.4  (abort with ^G)
>>> 1> local_server:start().
>>> <0.33.0>
>>> 2> received:"GET / HTTP/1.1\r\nUpgrade: WebSocket\r\nConnection:
>>> Upgrade\r\nHost: localhost:1234\r\nOrigin:
>>> http://localhost:2246\r\n\r\n"
>>> 2> received:[0,104,101,108,108,111,32,102,114,111,109,32,116,104,101,32,98,114,
>>>          111,119,115,101,114,255]
>>>
>>> Colm
>>>
>>
>> ________________________________________________________________
>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>> erlang-questions (at) erlang.org
>>
>
>
>
> --
> Jayson Vantuyl
> 
>
>
>
>
>
>


More information about the erlang-questions mailing list