Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 108 lines (63 sloc) 5.504 kb
a39fab8 @klacke added example docs on how to stream data
authored
1
2 <erl>
3
4
5 box(Str) ->
6 {'div',[{class,"box"}],
f6dbbc9 @klacke added possibility to name the module in a .yaws file
authored
7 {pre,[],yaws_api:htmlize(Str)}}.
a39fab8 @klacke added example docs on how to stream data
authored
8
9 tbox(T) ->
10 box(lists:flatten(io_lib:format("~p",[T]))).
11
12
13 ssi(File) ->
14 {'div',[{class,"box"}],
15 {pre,[],
16 {ssi, File,[],[]}}}.
17
18
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
19 out(A) ->
20ece13 @klacke more css hackery
authored
20 [{ssi, "TAB.inc", "%%",[{"stream", "choosen"}]},
a39fab8 @klacke added example docs on how to stream data
authored
21 {ehtml,
bea8261 @klacke added log_wrap_size, configurable wrap size for all logs, fixed a bug…
authored
22 {'div',[{id, "entry"}],
a39fab8 @klacke added example docs on how to stream data
authored
23 [{h1, [], "Streaming data to the client"},
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
24
a39fab8 @klacke added example docs on how to stream data
authored
25 {p, [],
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
26 "Sometimes we want to stream data to the client. Maybe we don't know or cannot compute the size of the data. Regardless of the reason, we do not want to keep all data in memory until it's shipped to the client. We want to use chunked encodings, and simply send data in chunks to the client. This is performed in steps. First the out/1 return value:"},
a39fab8 @klacke added example docs on how to stream data
authored
27
28 box(" {streamcontent, MimeType, FirstChunk}"),
29
30 {p,[], ["Is returned from the out/1 function"
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
31 " This makes the erlang process within yaws processing that particular page go into a receive loop, waiting for more data. Somehow, another process in the erlang system must then deliver data to the waiting/receiving erlang process. There are two asynchronous API functions that can be used to deliver that data."]},
32
a39fab8 @klacke added example docs on how to stream data
authored
33 box("yaws_api:stream_chunk_deliver(YawsPid, Data)"),
2f8bae9 @klacke ""
authored
34 {p, [], "and"},
a39fab8 @klacke added example docs on how to stream data
authored
35 box("yaws_api:stream_chunk_end(YawsPid)"),
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
36
2f8bae9 @klacke ""
authored
37 {p, [], "The YawsPid argument is the process identifier of the original yaws process processing the page, i.e. self(), in the .yaws file."},
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
38
39 {p, [],"Maybe this gets clear with a programming example, let's use a process reading a random number of bytes from /dev/urandom as the source of the data"},
40
a39fab8 @klacke added example docs on how to stream data
authored
41 ssi("urandom.yaws"),
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
42
43 {p, [],
44 ["The above slightly bizarre code can be executed ",
c4fd143 @vinoski add support for W3C Server-Sent Events
vinoski authored
45 {a, [{href, "urandom.yaws"}], "here"},
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
46 ". The code creates a process which reads a random amount of bytes from /dev/urandom and sends them to the client, piece by piece. "]},
47
48 {p,[], "There is also a version of the API that delivers the data in a blocking fashion. Whenever the producer of the stream is faster than the consumer, that is the WWW client, we must use a synchronous version of the code. The api function is called:"},
49
50 box("yaws_api:stream_chunk_deliver_blocking(YawsPid, Data)"),
51
52 {p,[],
53 "For applications that want to avoid buffering data in memory but do not want chunked transfer, or for applications that employ long-polling (Comet) techniques, another streamcontent variant lets the application send data directly on the client socket. Such applications should first return the following from their out/1 function:"},
54
55 box(" {streamcontent_from_pid, MimeType, Pid}"),
56
57 {p,[], "where the Pid argument is the pid of the application process that will send the data, and MimeType is the MIME type of the data to be sent. When yaws is ready for Pid, it sends one of the following messages to it:"},
58
59 {ul,[],
60 [{li,[]," {ok, YawsPid} indicates to Pid that it can send data over the socket, which is available as Arg#arg.clisock. YawsPid will be used later to tell yaws that Pid has finished streaming."},
61 {li,[]," {discard, YawsPid} indicates to Pid that it should avoid sending data to the socket. This is needed when the client invokes an HTTP request such as HEAD that has no response body."}]},
62
63 {p,[],"Pid can send data on the socket by calling:"},
64
913aff8 @vinoski Use iolists instead of binaries for streamcontent_from_pid data, and
vinoski authored
65 box(" yaws_api:stream_process_deliver(Socket, IoList)"),
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
66
913aff8 @vinoski Use iolists instead of binaries for streamcontent_from_pid data, and
vinoski authored
67 {p,[],"where IoList is the data to be sent. For chunked transfer, Pid must call:"},
a39fab8 @klacke added example docs on how to stream data
authored
68
913aff8 @vinoski Use iolists instead of binaries for streamcontent_from_pid data, and
vinoski authored
69 box(" yaws_api:stream_process_deliver_chunk(Socket, IoList)"),
a39fab8 @klacke added example docs on how to stream data
authored
70
913aff8 @vinoski Use iolists instead of binaries for streamcontent_from_pid data, and
vinoski authored
71 {p,[],"which tells yaws to use HTTP chunked transfer to send IoList. Applications using chunked transfer in this manner must always remember to end their data transfer by calling:"},
a39fab8 @klacke added example docs on how to stream data
authored
72
913aff8 @vinoski Use iolists instead of binaries for streamcontent_from_pid data, and
vinoski authored
73 box(" yaws_api:stream_process_deliver_final_chunk(Socket, IoList)"),
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
74
75
913aff8 @vinoski Use iolists instead of binaries for streamcontent_from_pid data, and
vinoski authored
76 {p,[],"where IoList is an iolist of size 0 or more. This creates the final HTTP chunk that the client uses to detect the end of the transfer."},
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
77
78 {p,[],"When Pid finishes sending data, or when it receives a {discard, YawsPid} message, it must call:"},
79
80 box(" yaws_api:stream_process_end(Socket, YawsPid)"),
81
82 {p,[],"This informs yaws that Pid is finished with the socket and will no longer use it directly."},
83
5da72a3 @vinoski Allow "stream processes" to close the client socket
vinoski authored
84 box(" yaws_api:stream_process_end(closed, YawsPid)"),
85
86 {p,[],"This informs yaws that Pid has not only finished with the socket, but has also closed it. Yaws will not attempt to use the socket anymore after the application calls this function."},
87
c4fd143 @vinoski add support for W3C Server-Sent Events
vinoski authored
88 {p,[],"Applications using streamcontent_from_pid should be sure to set a Content-Length header in their out/1 return value if they want to avoid chunked transfer encoding for their return value. Yaws automatically sets the HTTP Transfer-Encoding header to chunked if it doesn't detect a Content-Length header. Another alternative is to return the {header, {transfer_encoding, erase}} header from out/1 in order to disable chunked encoding."},
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
89
90 {p,[],"Here's an example of using streamcontent_from_pid:"},
91
92 ssi("urandom_from_pid.yaws"),
93
94 {p, [],
95 ["The above code can be executed ",
96 {a, [{href, "urandom_from_pid.yaws"}], "Here"},
97 ". The code creates a process which reads a random amount of bytes from /dev/urandom and sends them to the client via the socket. "]}
a39fab8 @klacke added example docs on how to stream data
authored
98
bea8261 @klacke added log_wrap_size, configurable wrap size for all logs, fixed a bug…
authored
99 ]}},
100 {ssi, "END2",[],[]}
101 ].
a39fab8 @klacke added example docs on how to stream data
authored
102
5f35f5b @vinoski add streamcontent_from_pid capability to allow direct streaming to so…
vinoski authored
103
a39fab8 @klacke added example docs on how to stream data
authored
104 </erl>
105
106
107 </html>
Something went wrong with that request. Please try again.