Network services
There are many times where you may want to open a port in Prosody from a module, and accept connections. This is done via 'net' providers.
The provider
The provider is just a simple table that contains info about the service.
Ports are a shared resource, so to avoid port conflicts with other modules in the same Prosody instance you should only add net providers from global or shared modules.
To add a provider, simply call:
local my_listener = {}; -- Listener object, explained below
:provides("net", {
module= 5432; -- Default port, can be overridden by config
default_port = my_listener;
listener });
As always with module:provides(),
you may set a 'name' field (not shown in the example). It is recommended
not to - the current module's name will be used by default (with
mod_
or mod_net_
stripped from the front).
After loading the example module above, you should be able to telnet
into Prosody: telnet localhost 5432
. It will all be silent
so far, so let's add some connection handling using that listener object
we created.
The listener
The most important thing you'll need is a 'listener'. This is an object that implements a few standard functions that get called in response to events on the port. The most common functions you'll need are:
onconnect
: A new incoming connectiononincoming
: A connection sent some dataondisconnect
: A connection closed
An example of a basic listener:
function my_listener.onconnect(conn)
:write("Hello!\n");
connend
function my_listener.onincoming(conn, data)
:write("You said "..data.."\n");
connend
function my_listener.ondisconnect(conn, err)
:log("info", "Connection closed: %s", err or "no error");
moduleend
After adding this to the module above, you should be able to telnet in, and type and receive responses.
Usually in anything more than a basic protocol you will want to keep
track of what connections are open, and store some information about
them. You can create a sessions
table, and use the
connection object as the index:
local my_listener = {};
local sessions = {};
function my_listener.onconnect(conn)
[conn] = {};
sessions:write("Hello!\n");
connend
function my_listener.onincoming(conn, data)
local session = sessions[conn];
local last_said = session.last_said;
.last_said = data; -- Save for next time
sessionif last_said then
:write("But last time you said "..last_said.."\n");
connelse
:write("Ok.\n");
connend
end
function my_listener.ondisconnect(conn, err)
[conn] = nil; -- Don't forget this!
sessions:log("info", "Connection closed: %s", err or "no error");
moduleend