luasocket/doc/callback.html
2004-01-21 06:33:47 +00:00

253 lines
7.3 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>LuaSocket: Network support for the Lua language</title>
<link rel="stylesheet" href="reference.css" type="text/css">
</head>
<body>
<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<div class=header>
<hr>
<center>
<table summary="LuaSocket logo">
<tr><td align=center><a href="http://www.lua.org">
<img border=0 alt="LuaSocket" src="luasocket.png">
</a></td></tr>
<tr><td align=center valign=top>Network support for the Lua language
</td></tr>
</table>
<p class=bar>
<a href="home.html">home</a> &middot;
<a href="home.html#download">download</a> &middot;
<a href="introduction.html">introduction</a> &middot;
<a href="reference.html">reference</a>
</p>
</center>
<hr>
</div>
<!-- stream ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<h2 id=stream>Streaming with Callbacks</h2>
<p>
HTTP, FTP, and SMTP transfers sometimes involve large amounts of
information. Sometimes an application needs to generate outgoing data
in real time, or needs to process incoming information as it is being
received. To address these problems, LuaSocket allows HTTP and SMTP message
bodies and FTP file contents to be received or sent through the
callback mechanism outlined below.
</p>
<p>
Instead of returning the entire contents of an entity
as strings to the Lua application, the library allows the user to
provide a <em>receive callback</em> that will be called with successive
chunks of data, as the data becomes available. Conversely, the <em>send
callbacks</em> can be used when the application wants to incrementally
provide LuaSocket with the data to be sent.
</p>
<!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=receive_cb>
ret, err_or_f = <b>receive_cb(</b>chunk, err<b>)</b>
</p>
<p class=description>
The callback provided by the user will be repeatedly called by the
library whenever new data is available. Each time it is called, the
callback receives successive chunks of downloaded data.
</p>
<p class=parameters>
<tt>Chunk</tt> contains the current chunk of data.
When the transmission is over, the function is called with an
empty string (i.e.&nbsp;<tt>""</tt>) as the <tt>chunk</tt>.
If an error occurs, the function receives <tt>nil</tt>
as <tt>chunk</tt> and an error message in <tt>err</tt>.
</p>
<p class=return>
The callback can abort transmission by returning <tt>nil</tt> as its first
return value, and an optional error message as the
second return value. If the application wants to continue receiving
data, the function should return non-<tt>nil</tt> as it's first return
value. In this case, the function can optionally return a
new callback function, to replace itself, as the second return value.
</p>
<p class=note>
Note: The <tt>callback</tt> module provides several standard receive callbacks, including the following:
</p>
<pre class=example>
function receive.concat(concat)
concat = concat or socket.concat.create()
local callback = function(chunk, err)
-- if not finished, add chunk
if chunk and chunk ~= "" then
concat:addstring(chunk)
return 1
end
end
return callback, concat
end
</pre>
<p class=note>
This function creates a new receive callback that concatenates all
received chunks into a the same concat object, which can later be
queried for its contents.
</p>
<!-- send_cb ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name>
chunk, err_or_r = <b>send_cb()</b>
</p>
<p class=description>
The callback provided by the user will be repeatedly called whenever the
library needs more data to be sent.
</p>
<p class=return>
Each time the callback is called, it should return the next chunk of data. It
can optionally return, as it's second return value, a new callback to replace
itself. The callback can abort the process at any time by returning
<tt>nil</tt> followed by an optional error message.
</p>
<p class=note>
Note: Below is the implementation of the <tt>callback.send.file</tt>
function. Given an open file handle, it returns a send callback that will send the contents of that file, chunk by chunk.
</p>
<pre class=example>
function send.file(file, io_err)
-- if successful, return the callback that reads from the file
if file then
return function()
-- send next block of data
return (file:read(BLOCKSIZE)) or ""
end
-- else, return a callback that just aborts the transfer
else return fail(io_err or "unable to open file") end
end
</pre>
<!-- predefined +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<h2 id=predefined>Predefined Callbacks</h2>
<p>
The module <tt>callback.lua</tt> provides several predefined callbacks to
perform the most common input/output operations. Callbacks are provided
that send and receive contents of files and strings. Furthermore,
composition functions are provided to chain callbacks with filters, such as
the filters defined in the <tt>mime.lua</tt> module.
</p>
<!-- send.file ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=send.file>
<b>send.file</b>(file, io_err<b>)</b>
</p>
<p class=description>
This function creates a send callback that will return the contents
of a the file, until the file has been entirely sent. When done, the
callback closes the file.
</p>
<p class=parameters>
<tt>File</tt> is a file open for reading. If <tt>file</tt> is
<tt>nil</tt>, <tt>io_err</tt> can contain an error message and the
returned callback just aborts transmission with the error message.
</p>
<p class=return>
Returns a send callback for the file.
</p>
<p class=note>
Note: The function is designed so that it directly accepts the return
values of the <tt>io.open</tt> function.
</p>
<!-- send.string ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=send.string>
<b>send.string(</b>str<b>)</b>
</p>
<p class=description>
This function creates a send callback that will send
the contents of a string.
</p>
<p class=parameters>
<tt>Str</tt> is the string to be sent.
</p>
<p class=return>
Returns a send callback for the string, or <tt>nil</tt> if the string is
<tt>nil</tt>.
</p>
<p class=note>
Note: If any function in the LuaSocket API receives a <tt>nil</tt>
send callback, it assumes there is nothing to be sent.
</p>
<!-- send.chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=send.string>
<b>send.chain(</b>send_cb, filter<b>)</b>
</p>
<p class=description>
This function creates a send callback that will send
all data that it gets from another callback,
after passing the data through a filter.
</p>
<p class=parameters>
<tt>Send_cb</tt> is the send callback to be chained to <tt>filter</tt>.
</p>
<p class=return>
Returns a callback chained with the filter.
</p>
(write a note!)
<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<div class=footer>
<hr>
<center>
<p class=bar>
<a href="home.html">home</a> &middot;
<a href="home.html#down">download</a> &middot;
<a href="introduction.html">introduction</a> &middot;
<a href="reference.html">reference</a>
</p>
<p>
<small>
Last modified by Diego Nehab on <br>
Sat Aug 9 01:00:41 PDT 2003
</small>
</p>
</center>
</div>
</body>
</html>