But I can't get past the handshake ...
<aside>
If we can get this working we can junk ajax, comet etc and do pure
socket bi-directional
stuff as the great ones intended. Erlang will then fit *beautifully*
with the broswer
code and we can start writing some great applications
</aside>
This posting
http://blog.chromium.org/2009/12/web-sockets-now-available-in-google.html
Got me pretty excited - I happen to have the latest chrome browser as
so a little test was in order ...
The handshake is described in
http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-55#page-22
So I set up a local web server on port 2246 that serves up this page
<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 received_msg = evt.data; alert("yes");
};
ws.onclose = function()
{
alert("closed");
};
} else {
alert("sad");
};
</script>
</body>
Then I have a server on port 1234 using this code
-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} ->
io:format("received:~p~n",[Data]),
loop(Socket);
Any ->
io:format("Received:~p~n",[Any]),
loop(Socket)
end.
It's beginning to work but now the handshake fails.
Very exciting stuff.
Be the first to get this working and tell us how
/Joe
________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org
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),
>
>
May be use a full URL instead of
"WebSocket-Location: ws://localhost:1234\r\n\r\n",
i.e.
"WebSocket-Location:
ws://localhost:1234/path/to/your/script\r\n\r\n",
?
I can't test at the moment
my christmas cents...
On Thu, Dec 10, 2009 at 10:21 AM, Joe Armstrong <erl...@gmail.com> 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
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 Dec 10, 1:56 pm, Joe Armstrong <erl...@gmail.com> 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 ...
>
This is incredibly awsome! I am sure this will inevitably change the
way we think about the web, clouds, the whole client-server
architecture in general within a short timespan.
Johann
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 ...
> --
> Jayson Vantuyl
> kag...@souja.net
Do you know, how antivirus handle endless HTTP stream? It waits
request end, save to disk and check there. This is why
endless-http is dead.
We are using RTMP in our production. It is a statefull binary
protocol. It is 100% unreliable, because lots of corporate proxies
don't allow it. And these proxies will not allow websockets.
Ingo
Sergej
Either I've missed something from documentation, either there is told
about statefull connection.
> And these proxies will not allow websockets.
>
With reverse HTTP how do you distinguish websockets from normal HTTP
requests?
--
Tony Arcieri
Medioh! A Kudelski Brand
On Dec 10, 4:32 pm, Rapsey <rap...@gmail.com> wrote:
> Isn't it designed to work through HTTP? It's definitely a much better
> solution than what is available for comet.
________________________________________________________________
What about proxy servers, I hope they will be redesigned to let WS work.
Look, from server point of view, there is no difference between comet
and web socket.
Differs only the common time of being connected.
--Senthil
--
Regards,
Senthilkumar Peelikkampatti,
http://pmsenthilkumar.blogspot.com/
Another group should do an in-line chat engine
Use a DHT for the users and we could make an infinitly scabale IRC engine :-)
/Joe
Firefox also implemented Websocket but code is still in trunck for
almost an year. It is the first one before chrome implemented but it
the chrome came to market first. Whole history can be found at
https://bugzilla.mozilla.org/show_bug.cgi?id=472529.
On Thu, Dec 10, 2009 at 5:17 PM, Senthilkumar Peelikkampatti
--
--Hynek (Pichi) Vychodil
Analyze your data in minutes. Share your insights instantly. Thrill
your boss. Be a data hero!
Try Good Data now for free: www.gooddata.com
yeah I wish they would quit redefining new protocols, I try and use
BEEP when ever possible.
It is way more featureful than this new web sockets stuff from a
developers point of view.
It handles most cases and you can transport text or binary or whatever you want.
In the real world site owners are beginning to get their hopes up
about dropping support for IE6, an eight year old browser, soon.
Hopefully we don't have to wait as long as eight years for IE7's
market share to dwindle enough to be ignorable, but I'm not holding my
breath waiting for ajax and comet to be superseded in any practical
setting.
(I have two deployed apps using combinations of forever-frames, long
polling and other HTTP/browser abuses, and it's a disgusting mess.)
> Look, from server point of view, there is no difference between comet
> and web socket.
> Differs only the common time of being connected.
>
Comet uses "long polling". The client connects, sends a request, and the
server doesn't respond until an event is occurred. The client socket can
time out, in which case it reconnects. When the client gets a response, it
consumes it and closes the socket. Once the event is processed, the client
makes a new long polling connection to the server.
Websockets let you use RHTTP. The client connects, sends a request to
switch to RHTTP, then becomes an HTTP server. This is a true push model, as
opposed to Comet long polling. The remote can push an unlimited number of
events back to the client via RHTTP, as the client is now acting as a
server. The connection between the client and server is never dropped
unless something goes wrong, as opposed to Comet where the connection is
dropped once per event at a minimum.