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

Joe Armstrong <>
Thu Dec 10 13:56:28 CET 2009


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
>


More information about the erlang-questions mailing list