| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#!perl |
|
2
|
1
|
|
|
1
|
|
1800
|
use v5.36; |
|
|
1
|
|
|
|
|
5
|
|
|
3
|
1
|
|
|
1
|
|
7
|
use PXF::Util (); |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
38
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package StreamingApp { |
|
6
|
1
|
|
|
1
|
|
7
|
use PlackX::Framework; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
10
|
|
|
7
|
1
|
|
|
1
|
|
7
|
use StreamingApp::Router; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
29
|
|
|
8
|
|
|
|
|
|
|
route '/stream-example' => sub ($request, $response) { |
|
9
|
|
|
|
|
|
|
# This part is not streaming |
|
10
|
|
|
|
|
|
|
$response->print("\n"); |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# Many browsers will buffer the response until several KB have been sent |
|
13
|
|
|
|
|
|
|
# Some seem to always buffer (Safari), others always stream (Chrome) |
|
14
|
|
|
|
|
|
|
# If server is behind a reverse proxy you have even more to worry about |
|
15
|
|
|
|
|
|
|
$response->print("\n" x 1024); |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# Here is the streaming part |
|
18
|
|
|
|
|
|
|
return $response->render_stream(sub { |
|
19
|
|
|
|
|
|
|
# Only use $response->print() inside the code block |
|
20
|
|
|
|
|
|
|
# Calling other methods on the $response object will not make sense |
|
21
|
|
|
|
|
|
|
# PXF will emulate PSGI streaming if it is not available. |
|
22
|
|
|
|
|
|
|
for my $i (0..5) { |
|
23
|
|
|
|
|
|
|
$response->print("Hello $i \n"); |
|
24
|
|
|
|
|
|
|
# Simulate a slow response with sleep |
|
25
|
|
|
|
|
|
|
# sleep 1; |
|
26
|
|
|
|
|
|
|
PXF::Util::minisleep($i/10); |
|
27
|
|
|
|
|
|
|
} |
|
28
|
|
|
|
|
|
|
$response->print("\n"); |
|
29
|
|
|
|
|
|
|
}); |
|
30
|
|
|
|
|
|
|
}; |
|
31
|
|
|
|
|
|
|
} |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
StreamingApp->app; |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=pod |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
This is what a similar streaming app would look like with straight PSGI |
|
38
|
|
|
|
|
|
|
(minus the html above): |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
my $app = sub { |
|
41
|
|
|
|
|
|
|
my $env = shift; |
|
42
|
|
|
|
|
|
|
return sub { |
|
43
|
|
|
|
|
|
|
my $responder = shift; |
|
44
|
|
|
|
|
|
|
my $writer = $responder->([200, ['Content-Type' => 'text/html']]); |
|
45
|
|
|
|
|
|
|
$writer->write("I am about to stream...\n"); |
|
46
|
|
|
|
|
|
|
for my $i (0..10) { |
|
47
|
|
|
|
|
|
|
$writer->write("Hello $i\n"); |
|
48
|
|
|
|
|
|
|
sleep 1; |
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
$writer->close; |
|
51
|
|
|
|
|
|
|
}; |
|
52
|
|
|
|
|
|
|
}; |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
PlackX::Framework supports streaming body, but does not support delayed response |
|
55
|
|
|
|
|
|
|
at this time (headers are sent immediately). |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
Simply call $response->stream with a coderef and print your content to the same |
|
58
|
|
|
|
|
|
|
response object. |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
The coderef return value is ignored, but don't forget to return your $response |
|
61
|
|
|
|
|
|
|
object at the end of your route action, to send the response headers and |
|
62
|
|
|
|
|
|
|
coderef to PXF. |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
If the server does not support PSGI streaming, then PXF's streaming interface |
|
65
|
|
|
|
|
|
|
will be emulated. |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
The PSGI writer, $response->stream_writer, should not be used directly. |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
PXF does not handle the Content-Encoding header, but most HTTP 1.1 servers will |
|
70
|
|
|
|
|
|
|
take care of this. It has been tested and works correctly with perl/PSGI |
|
71
|
|
|
|
|
|
|
servers Starman, Starlet, and Gazelle. |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
The default plackup server, HTTP::Server::PSGI, is a HTTP 1.0 server and will |
|
74
|
|
|
|
|
|
|
not chunk the response. User agents (most consumer-grade web browsers) are more |
|
75
|
|
|
|
|
|
|
likely to buffer these responses. |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
You are encouraged to put newlines at the end of each $response->print call to |
|
78
|
|
|
|
|
|
|
encourage the server to clear the buffer and send the line to the client. |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
Note Plack supports setting the body to an IO-Handle-like object. Mixing this |
|
81
|
|
|
|
|
|
|
type of "special" body with PXF print() and body() statements is not supported |
|
82
|
|
|
|
|
|
|
and will result in undefined behavior. |