<p>I'm not sure I understand what you're saying here. I think we might have our wires crossed or I've not explained myself very well. </p>
<p>Web servers communicate over TCP. Therefore until the point that either the servers established TCP connection detects that the client has connected or timed out, it will be able to tell how much data has been successfully send and acknowledged as received by the client browser. This is a function of the underlying TCP network connection. I'm simply looking for a way to get at this socket level information as exposed to the PSGI application through the web server. </p>
<div class="gmail_quote">On Dec 22, 2013 3:57 PM, "Daniel Perrett" <<a href="mailto:dperrett@cambridge.org">dperrett@cambridge.org</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<font face="Default Sans Serif,Verdana,Arial,Helvetica,sans-serif">As far as I understand it, this is impossible with any HTTP server, because once a client makes an HTTP request, the server processes it and responds - and there is no communication between them in the mean time. A server has no way of knowing if the client is still interested, and the server cannot initiate contact with the client. You could pull some tricks to demand multiple HTTP requests (generate 3xx responses on the fly to play for time), but this is likely to be a headache, and from the sounds of it won't fit your use case either. WebSockets might help you, but I don't know much about them, and I don't think it will work if you don't have any control over the client.<div>
<br></div><div>To me it sounds like the root of the problem is you are offering to do resource-intensive tasks for unidentifiable users where the only thing you know about them is that they have the URL.</div><div><div><br>
</div><div>Daniel<br><br><font color="#990099">-----<a href="mailto:dancer-users-bounces@dancer.pm" target="_blank">dancer-users-bounces@dancer.pm</a> wrote: -----</font><div style="padding-left:5px"><div style="padding-right:0px;padding-left:5px;border-left:solid black 2px">
To: Perl Dancer users mailing list <<a href="mailto:dancer-users@dancer.pm" target="_blank">dancer-users@dancer.pm</a>><br>From: Nicola Worthington <u></u><br>Sent by: <a href="mailto:dancer-users-bounces@dancer.pm" target="_blank">dancer-users-bounces@dancer.pm</a><br>
Date: 12/21/2013 12:57PM<br>Subject: Re: [dancer-users] Detecting disconnected HTTP clients during streamed output<br><br><div dir="ltr">That's certainly a possibility, but since this app is primarily aimed at mobile devices that will be landing directly on stream URLs (for the most part not launched from their browser but through a handful of other apps that will simply make a call to the OS to open a URL for them to stream media directly) it would make this approach less than idea and not as robust as I was hoping for. :( </div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On 21 December 2013 03:52, Matthew Mallard <span dir="ltr"><<a href="mailto:mqm@q-technologies.com.au" target="_blank">mqm@q-technologies.com.au</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
Just an idea.<br>
<br>
Why don't you use ajax and only allow on conversion per user at a
time. You can create an ajax query to check on progress, plus the
user can cancel. Basically detach the conversion from the web
client, but allow client to check on progress and have access to the
file when it has finished.<div><div><br>
<br>
<div>On 21/12/2013 5:40 am, Nicola
Worthington wrote:<br>
</div>
</div></div><blockquote type="cite"><div><div>
<div dir="ltr">I have a handler that transcodes video files using
ffmpeg which all works fine. However, if the web client
disconnects or otherwise stops reading from the socket, my
handler will continue reading from the ffmpeg filehandle and
writing out to the writer object until ffmpeg has completed the
transcode.
<div>
<br>
</div>
<div>This wouldn't be a problem is we lived in a perfect world
where every web client would send a single request to a URL
and not make additional requests until the first one had been
completed, but of course we don't live in an ideal world,..
and I would prefer my webapp not kill the server it is running
on my spawning off more CPU intensive processes than
necessary.</div>
<div><br>
</div>
<div>Is there any way for me to determine how much data is sat
waiting to be flushed to the web client so that if it exceeded
a predetermined number of bytes I can assume that I should
kill my ffmpeg file handle and exit the handler prematurely,..
or any other way to determine if the web client has gone away?</div>
<div><br>
</div>
<div>Apologies if I haven't explained myself especially
articulately.</div>
<div><br>
</div>
<div>This is the handler in question:</div>
<div><br>
</div>
<div>
<div><font face="courier new, monospace"><b>get
'/stream/:file/:format' => sub {</b></font></div>
<div><font face="courier new, monospace"><b> my $file =
params->{file};</b></font></div>
<div><b style="font-family:'courier new',monospace"> my
$format = params->{format};</b><br>
</div>
<div><font face="courier new, monospace"><b><br>
</b></font></div>
<div><font face="courier new, monospace"><b> return
send_file(</b></font></div>
<div><font face="courier new, monospace"><b>
'favicon.ico',</b></font></div>
<div><font face="courier new, monospace"><b> streaming
=> 1,</b></font></div>
<div><font face="courier new, monospace"><b> callbacks
=> {</b></font></div>
<div><font face="courier new, monospace"><b>
override => sub {</b></font></div>
<div><font face="courier new, monospace"><b> my
($respond, $response) = @_;</b></font></div>
<div><font face="courier new, monospace"><b><br>
</b></font></div>
<div><b style="font-family:'courier new',monospace">
my $mime = 'video/mp4';</b><br>
</div>
<div><font face="courier new, monospace"><b> my
@ffmpeg_args = qw(-threads 0 -i $file);</b></font></div>
<div><b style="font-family:'courier new',monospace"><br>
</b></div>
<div><b style="font-family:'courier new',monospace">
if (exists $ffmpeg_formats{$format}) {</b><br>
</div>
<div><font face="courier new, monospace"><b>
$mime = 'video/' . $format;</b></font></div>
<div><font face="courier new, monospace"><b>
push @ffmpeg_args, @{$ffmpeg_formats{$format}};</b></font></div>
<div><font face="courier new, monospace"><b> }
else {</b></font></div>
<div><font face="courier new, monospace"><b>
push @ffmpeg_args, @{$ffmpeg_formats{mp4}};</b></font></div>
<div><font face="courier new, monospace"><b> }</b></font></div>
<div><font face="courier new, monospace"><b>
push @ffmpeg_args, '-';</b></font></div>
<div><font face="courier new, monospace"><b><br>
</b></font></div>
<div><font face="courier new, monospace"><b> my
$writer = $respond->([200, ['Content-Type' =>
$mime]]);</b></font></div>
<div><font face="courier new, monospace"><b>
open(my $fh, '-|', join(' ', '/usr/bin/ffmpeg',
@ffmpeg_args));</b></font></div>
<div><font face="courier new, monospace"><b> my
$buffer;</b></font></div>
<div><font face="courier new, monospace"><b>
while (read($fh, $buffer, 1024) ) {</b></font></div>
<div><font face="courier new, monospace"><b>
$writer->write($buffer);</b></font></div>
<div><font face="courier new, monospace"><b> }</b></font></div>
<div><font face="courier new, monospace"><b>
close($fh);</b></font></div>
<div><font face="courier new, monospace"><b> },</b></font></div>
<div><font face="courier new, monospace"><b> },</b></font></div>
<div><font face="courier new, monospace"><b> );</b></font></div>
<div><font face="courier new, monospace"><b>};</b></font></div>
</div>
<div><br>
</div>
<div>
<div><br>
</div>
-- <br>
<div dir="ltr">Nicola Worthington<br>
<div><a href="mailto:nicolaw@tfb.net" target="_blank">nicolaw@tfb.net</a><br>
</div>
<div><br>
</div>
</div>
</div>
</div>
<br>
<fieldset></fieldset>
<br>
</div></div><div><font face="Courier New,Courier,monospace" size="3">_______________________________________________<br>dancer-users mailing list<br><a href="mailto:dancer-users@dancer.pm" target="_blank">dancer-users@dancer.pm</a><br>
<a href="http://lists.preshweb.co.uk/mailman/listinfo/dancer-users" target="_blank">http://lists.preshweb.co.uk/mailman/listinfo/dancer-users</a><br></font></div>
</blockquote>
<br>
</div>
<br>_______________________________________________<br>
dancer-users mailing list<br>
<a href="mailto:dancer-users@dancer.pm" target="_blank">dancer-users@dancer.pm</a><br>
<a href="http://lists.preshweb.co.uk/mailman/listinfo/dancer-users" target="_blank">http://lists.preshweb.co.uk/mailman/listinfo/dancer-users</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div dir="ltr">Nicola Worthington<br><div><a href="tel:%2B44%20%280%293333%20406%20333" value="+443333406333" target="_blank">+44 (0)3333 406 333</a></div>
<div><a href="mailto:nicolaw@tfb.net" target="_blank">nicolaw@tfb.net</a></div><div><br>
</div></div>
</div>
<div><font face="Courier New,Courier,monospace" size="3">_______________________________________________<br>dancer-users mailing list<br><a href="mailto:dancer-users@dancer.pm" target="_blank">dancer-users@dancer.pm</a><br>
<a href="http://lists.preshweb.co.uk/mailman/listinfo/dancer-users" target="_blank">http://lists.preshweb.co.uk/mailman/listinfo/dancer-users</a><br></font></div><u></u></div></div></div></div><div></div></font><br>_______________________________________________<br>
dancer-users mailing list<br>
<a href="mailto:dancer-users@dancer.pm">dancer-users@dancer.pm</a><br>
<a href="http://lists.preshweb.co.uk/mailman/listinfo/dancer-users" target="_blank">http://lists.preshweb.co.uk/mailman/listinfo/dancer-users</a><br>
<br></blockquote></div>