I also experimented with comet pattern, and for iframe transport type, If I remember propperly, I sent after each 25 seconds a keep alive message to the browser, to prevent the 30 second timeout and to detect a disconnected browser, so  I can kill that yaws worker process.

On 2/11/07, Tobias Oberstein <tobias.oberstein@gmx.de> wrote:
I'm experimenting with Yaws and the "Comet Pattern", which is about
sending real asynchronous stuff to the browser.

A browser portable way is i.e. having a hidden IFRAME which receives
MIME type text/html with content pieces of JS script tags which in
turn manipulate the main HTML DOM. Browsers will eval JS tags "as they
arrive" (incremental rendering).

see for example:

http://ajaxian.com/archives/iframe-script-tags-portable-comet
http://ajaxify.com/run/streaming/xmlHttpRequest/iframe/scriptTags/

and description of what I did below.

It's whats called "forever frame" in the following

http://alex.dojotoolkit.org/wp-content/LowLatencyData.pdf

versus the "long poll" technique.

--

Unfortunately, there seems to be a hard-coded timeout of 30s in
yaws_server.erl for streaming content.

I've attached a patch (for yaws_server.erl as it comes with Yaws 1.68)
which allows

out/1

in Yaws to produce 2 new return values

{streamcontent_with_timeout, MimeType, FirstChunk, TimeOut}
{streamcontent_with_size_and_timeout, Sz, MimeType, FirstChunk, TimeOut}

which enables the user to set the timeout for streaming content,
including setting the TimeOut = infinity.

--

The patch seems to work, but I'm a total Erlang newbie .. so if someone
likes to use it, please QA it .. (in particular, I've not used/tested
the streamcontent_with_size_and_timeout stuff .. just extended it for
symmetry reasons).

Tobias



============

Details.

The content I produce in Yaws for the IFRAME contains only one
<erl></erl> piece which subscribes the Yaws worker process to a
registered (named) process P, and returns

  {streamcontent, "text/html", "<html><body>"}.

Then, P will send JS script tags to all subscriber Yaws streaming
processes using

yaws_api:stream_chunk_deliver(..., "<script
type="text/javascript">window.parent.onData(5);</script>").

--

Problem is, when P does not send anything for some time, the Yaws
streaming worker dies with

=ERROR REPORT==== 11-Feb-2007::15:59:45 ===
Yaws process died: {stream_timeout,[{yaws_server,stream_loop_send,3},
                                     {yaws_server,aloop,3},
                                     {yaws_server,acceptor0,2},
                                     {proc_lib,init_p,5}]}

--

I've looked for "stream_timeout", seems to be produced in fun

stream_loop_send(Priv, CliSock, FlushStatus) ->
     TimeOut = case FlushStatus of
         flushed -> 30000;
         unflushed -> 300
          end,
     receive
  ...
of yaws_server.erl, which seems to hit the hardcoded timeout of 30s.

--

I've verified, that after hacking above line

"flushed -> 30000"

for

"flushed -> 120000"

and recompiling yaws_server.erl, both Firefox 2 and IE 7 will
not timeout by themselfes, but still receive asynchronous JS tags
via the IFRAME even after 110s inactivity.

--

With the attached patch, one is able to set the timeout

{streamcontent_with_timeout, "text/html", "<html><body>", infinity}.

from the .yaws page and both Firefox/IE will receive tags "forever".

I've tested IE7 for a waiting time of 15min between tags sent. No
problem, IE itself does not timeout.

--



--- yaws_server.erl.original    Sun Feb 11 16:28:03 2007
+++ yaws_server.erl     Sun Feb 11 18:02:33 2007
@@ -1906,13 +1906,25 @@
            accumulate_content(FirstChunk),
            Priv = deliver_accumulated(Arg, CliSock,
                                       decide, undefined, stream),
-           stream_loop_send(Priv, CliSock);
+           stream_loop_send(Priv, CliSock, 30000);
+       {streamcontent_with_timeout, MimeType, FirstChunk, TimeOut} ->
+           yaws:outh_set_content_type(MimeType),
+           accumulate_content(FirstChunk),
+           Priv = deliver_accumulated(Arg, CliSock,
+                                      decide, undefined, stream),
+           stream_loop_send(Priv, CliSock, TimeOut);
        {streamcontent_with_size, Sz, MimeType, FirstChunk} ->
            yaws:outh_set_content_type(MimeType),
            accumulate_content(FirstChunk),
            Priv = deliver_accumulated(Arg, CliSock,
                                       decide, Sz, stream),
-           stream_loop_send(Priv, CliSock);
+           stream_loop_send(Priv, CliSock, 30000);
+       {streamcontent_with_size_and_timeout, Sz, MimeType, FirstChunk, TimeOut} ->
+           yaws:outh_set_content_type(MimeType),
+           accumulate_content(FirstChunk),
+           Priv = deliver_accumulated(Arg, CliSock,
+                                      decide, Sz, stream),
+           stream_loop_send(Priv, CliSock, TimeOut);
        _ ->
            DeliverCont(Arg)
     end.
@@ -1981,31 +1993,31 @@
     finish_up_dyn_file(ARG, CliSock).


-stream_loop_send(Priv, CliSock) ->
-    stream_loop_send(Priv, CliSock, unflushed).
+stream_loop_send(Priv, CliSock, TimeOut) ->
+    stream_loop_send(Priv, CliSock, TimeOut, unflushed).

-stream_loop_send(Priv, CliSock, FlushStatus) ->
-    TimeOut = case FlushStatus of
-                 flushed -> 30000;
+stream_loop_send(Priv, CliSock, TimeOut, FlushStatus) ->
+    ThisTimeOut = case FlushStatus of
+                 flushed -> TimeOut;
                  unflushed -> 300
              end,
     receive
        {streamcontent, Cont} ->
            P = send_streamcontent_chunk(Priv, CliSock, Cont),
-           stream_loop_send(P, CliSock, unflushed) ;
+           stream_loop_send(P, CliSock, TimeOut, unflushed) ;
        {streamcontent_with_ack, From, Cont} -> % acknowledge after send
            P = send_streamcontent_chunk(Priv, CliSock, Cont),
            From ! {self(), streamcontent_ack},
-           stream_loop_send(P, CliSock, unflushed) ;
+           stream_loop_send(P, CliSock, TimeOut, unflushed) ;
        endofstreamcontent ->
            end_streaming(Priv, CliSock)
-    after TimeOut ->
+    after ThisTimeOut ->
            case FlushStatus of
                flushed ->
                    erlang:fault(stream_timeout);
                unflushed ->
                    P = sync_streamcontent(Priv, CliSock),
-                   stream_loop_send(P, CliSock, flushed)
+                   stream_loop_send(P, CliSock, TimeOut, flushed)
            end
     end.

@@ -2237,6 +2249,11 @@
     yaws:outh_set_content_type(MimeType),
     {streamcontent, MimeType, First};

+handle_out_reply({streamcontent_with_timeout, MimeType, First, TimeOut},
+                _LineNo,_YawsFile, _UT, _A) ->
+    yaws:outh_set_content_type(MimeType),
+    {streamcontent_with_timeout, MimeType, First, TimeOut};
+
handle_out_reply(Res = {page, _Page},
                 _LineNo,_YawsFile, _UT, _A) ->
     Res;
@@ -2246,6 +2263,11 @@
     yaws:outh_set_content_type(MimeType),
     {streamcontent_with_size, Sz, MimeType, First};

+handle_out_reply({streamcontent_with_size_and_timeout, Sz, MimeType, First, TimeOut},
+                _LineNo,_YawsFile, _UT, _A) ->
+    yaws:outh_set_content_type(MimeType),
+    {streamcontent_with_size_and_timeout, Sz, MimeType, First, TimeOut};
+
handle_out_reply({header, H},  _LineNo, _YawsFile, _UT, _A) ->
     yaws:accumulate_header(H);


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Erlyaws-list mailing list
Erlyaws-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/erlyaws-list




--
Roberto Saccon