Why not adopt me?
NAME
POEx::IRC::Backend - IRC client or server backend
SYNOPSIS
use POE;
use POEx::IRC::Backend;
POE::Session->create(
package_states => [
main => [ qw/
_start
ircsock_registered
ircsock_input
/ ],
],
);
sub _start {
# Spawn a Backend and register as the controlling session:
my $backend = POEx::IRC::Backend->spawn;
$_[HEAP]->{backend} = $backend;
$_[KERNEL]->post( $backend->session_id, 'register' );
}
sub ircsock_registered {
my $backend = $_[HEAP]->{backend};
# Listen for incoming IRC traffic:
$backend->create_listener(
bindaddr => $addr,
port => $port,
);
# Connect to a remote endpoint:
$backend->create_connector(
remoteaddr => $remote,
remoteport => $remoteport,
# Optional:
bindaddr => $bindaddr,
ipv6 => 1,
ssl => 1,
);
}
# Handle and dispatch incoming IRC events:
sub ircsock_input {
# POEx::IRC::Backend::Connect obj:
my $this_conn = $_[ARG0];
# IRC::Message::Object obj:
my $input_obj = $_[ARG1];
my $cmd = $input_obj->command;
# ... dispatch, etc ...
}
DESCRIPTION
A POE IRC socket handler that can be used (by client or server implementations) to speak the IRC protocol to endpoints via IRC::Message::Object objects.
Inspired by POE::Component::Server::IRC::Backend & POE::Component::IRC.
This is a very low-level interface to IRC sockets; the goal is to provide all the necessary scaffolding to develop stateless or stateful IRC clients and daemons. See POEx::IRC::Client::Lite for an experimental IRC client library using this backend (and the "SEE ALSO" section of this documentation for related tools).
Attributes
controller
Retrieve the POE::Session ID for the backend's registered controller.
Predicate: has_controller
connectors
A HASH of active Connector objects, keyed on their wheel ID.
filter
A POE::Filter::Stackable instance consisting of the current "filter_irc" stacked with "filter_line" (at the time the attribute is built).
filter_irc
A POE::Filter::IRCv3 instance with colonify disabled, by default (this behavior changed in v0.27.2).
A server-side Backend may want a colonifying filter:
my $backend = POEx::IRC::Backend->new(
filter_irc => POE::Filter::IRCv3->new(colonify => 1),
...
);
filter_line
A POE::Filter::Line instance.
listeners
HASH of active Listener objects, keyed on their wheel ID.
session_id
Returns the backend's session ID.
ssl_context
Returns the Net::SSLeay Context object, if we have one (or undef
if not); the context is set up by "spawn" if ssl_opts
are specified.
wheels
HASH of actively connected wheels, keyed on their wheel ID.
Methods
spawn
my $backend = POEx::IRC::Backend->spawn(
## Optional, needed for SSL-ified server-side sockets
ssl_opts => [
'server.key',
'server.cert',
],
);
Creates the backend's POE::Session.
The ssl_opts
ARRAY is passed directly to "SSLify_ContextCreate" in POE::Component::SSLify, if present. As of v0.28.x
, each Backend gets its own Net::SSLeay context object (rather than sharing the global context). See POE::Component::SSLify & Net::SSLeay.
create_connector
$backend->create_connector(
remoteaddr => $addr,
remoteport => $addr,
## Optional:
bindaddr => $local_addr,
ipv6 => 1,
ssl => 1,
## Unrecognized opts are stored in the Connector's 'args' hash:
tag => 'foo',
);
Attempts to create a POEx::IRC::Backend::Connector that holds a POE::Wheel::SocketFactory connector wheel; connectors will attempt to establish an outgoing connection immediately.
Unrecognized options are stored in the POEx::IRC::Backend::Connector's args
HASH-type attribute; this is passed to successfully created POEx::IRC::Backend::Connect instances (as of v0.26.x
). Note that the reference is shared, not copied.
create_listener
$backend->create_listener(
bindaddr => $addr,
port => $port,
## Optional:
ipv6 => 1,
ssl => 1,
idle => $seconds,
);
Attempts to create a POEx::IRC::Backend::Listener that holds a POE::Wheel::SocketFactory listener wheel.
Unrecognized arguments will be added to the Listener object's args
attribute, which is then passed on to POEx::IRC::Backend::Connect objects created by incoming connections to that listener, similar to the behavior described in "create_connector" (as of v0.28.x
).
remove_listener
$backend->remove_listener(
listener => $listener_id,
);
## or via addr, port, or combination thereof:
$backend->remove_listener(
addr => '127.0.0.1',
port => 6667,
);
Removes a listener and clears its wheel attribute; the socket shuts down when the POE::Wheel::SocketFactory wheel goes out of scope.
disconnect
$backend->disconnect($wheel_id, $disconnect_string);
Given a POEx::IRC::Backend::Connect or its wheel_id
, mark the specified wheel for disconnection.
This method will warn if the given wheel_id
cannot be found, which may be due to the connection disappearing prior to calling disconnect
.
You can avoid spurious warnings by checking if the POEx::IRC::Backend::Connect still has an active wheel attached:
if ($this_conn->has_wheel) {
$backend->disconnect( $this_conn )
}
Note that disconnection typically happens after a buffer flush; if your software does not perform entirely like a traditional platform (server implementations will typically send ERROR: Closing Link
or similar to clients marked for disconnection, which will trigger a buffer flush) you may currently experience "late" disconnects. See "disconnect_now".
disconnect_now
Like "disconnect", but attempt to destroy the wheel immediately (without waiting for a buffer flush).
send
$backend->send(
{
prefix => $prefix,
params => [ @params ],
command => $cmd,
},
@connect_ids
);
use IRC::Message::Object 'ircmsg';
my $msg = ircmsg(
command => 'PRIVMSG',
params => [ $chan, $string ],
);
$backend->send( $msg, $connect_obj );
Feeds POE::Filter::IRCv3 and sends the resultant raw IRC line to the specified connection wheel ID(s) or POEx::IRC::Backend::Connect object(s).
Accepts either an IRC::Message::Object or a HASH compatible with POE::Filter::IRCv3 -- look there for details.
Note that unroutable (target connection IDs with no matching live wheel) messages are silently dropped. You can check "wheels" yourself before sending if this behavior is unwanted:
for my $target (@connect_ids) {
unless (exists $backend->wheels->{$target}) {
warn "Cannot send to nonexistant target '$target'";
next
}
$backend->send(
{ prefix => $prefix, params => [ @params ], command => $cmd },
$target
);
}
has_ssl_support
Returns true if POE::Component::SSLify was successfully loaded.
has_zlib_support
Returns true if POE::Filter::Zlib::Stream was successfully loaded.
set_compressed_link
$backend->set_compressed_link( $conn_id );
Mark a specified connection wheel ID as pending compression; POE::Filter::Zlib::Stream will be added to the filter stack when the next flush event arrives.
This method will die unless "has_zlib_support" is true.
set_compressed_link_now
$backend->set_compressed_link_now( $conn_id );
Add a POE::Filter::Zlib::Stream to the connection's filter stack immediately, rather than upon next flush event.
This method will die unless "has_zlib_support" is true.
unset_compressed_link
$backend->unset_compressed_link( $conn_id );
Remove POE::Filter::Zlib::Stream from the connection's filter stack.
Received events
register
$poe_kernel->post( $backend->session_id,
'register'
);
Register the sender session as the backend's controller session. The last session to send 'register' is the session that receives notification events from the backend component.
create_connector
Event interface to create_connector -- see "Methods"
create_listener
Event interface to create_listener -- see "Methods"
remove_listener
Event interface to remove_listener -- see "Methods"
send
Event interface to /send -- see "Methods"
shutdown
Disconnect all wheels and clean up.
Dispatched events
These events are dispatched to the controller session; see "register".
ircsock_compressed
Dispatched when a connection wheel has had a compression filter added.
$_[ARG0]
is the connection's POEx::IRC::Backend::Connect.
ircsock_connection_idle
Dispatched when a connection wheel has had no input for longer than specified idle time (see "create_listener" regarding idle times).
Currently these events are only issued for incoming Connects accepted on a Listener, not outgoing Connects created by a Connector; if you need to do ping/pong-style heartbeating on an outgoing Connector-spawned socket, you will need to run your own timer.
$_[ARG0]
is the connection's POEx::IRC::Backend::Connect.
See also: "ping_pending" in POEx::IRC::Backend::Connect
ircsock_connector_failure
Dispatched when a Connector has failed due to some sort of socket error.
$_[ARG0]
is the connection's POEx::IRC::Backend::Connector with wheel() cleared.
@_[ARG1 .. ARG3]
contain the socket error details reported by POE::Wheel::SocketFactory; operation, errno, and errstr, respectively.
ircsock_connector_open
Dispatched when a Connector has established a connection to a peer.
$_[ARG0]
is the POEx::IRC::Backend::Connect for the connection.
ircsock_disconnect
Dispatched when a connection wheel has been cleared.
$_[ARG0]
is the connection's POEx::IRC::Backend::Connect with wheel() cleared.
ircsock_input
Dispatched when there is some IRC input from a connection wheel.
$_[ARG0]
is the connection's POEx::IRC::Backend::Connect.
$_[ARG1]
is an IRC::Message::Object.
ircsock_listener_created
Dispatched when a POEx::IRC::Backend::Listener has been created.
$_[ARG0]
is the POEx::IRC::Backend::Listener instance; the instance's port() is altered based on getsockname() details after socket creation and before dispatching this event.
ircsock_listener_failure
Dispatched when a Listener has failed due to some sort of socket error.
$_[ARG0]
is the POEx::IRC::Backend::Listener object.
@_[ARG1 .. ARG3]
contain the socket error details reported by POE::Wheel::SocketFactory; operation, errno, and errstr, respectively.
ircsock_listener_open
Dispatched when a listener accepts a connection.
$_[ARG0]
is the connection's POEx::IRC::Backend::Connect
$_[ARG1]
is the connection's POEx::IRC::Backend::Listener
ircsock_listener_removed
Dispatched when a Listener has been removed.
$_[ARG0]
is the POEx::IRC::Backend::Listener object.
ircsock_registered
Dispatched when a "register" event has been successfully received, as a means of acknowledging the controlling session.
$_[ARG0]
is the Backend's $self
object.
BUGS
Probably lots. Please report them via RT, e-mail, IRC (irc.cobaltirc.org#perl
), or GitHub (http://github.com/avenj/poex-irc-backend).
SEE ALSO
POEx::IRC::Backend::Role::Socket
POEx::IRC::Backend::Role::HasEndpoint
POEx::IRC::Backend::Role::HasWheel
POEx::IRC::Client::Lite for an experimental IRC client library using this backend.
https://github.com/miniCruzer/irssi-bouncer for an irssi-based bouncer/proxy system using this backend.
POE::Filter::IRCv3 and IRC::Message::Object for documentation regarding IRC message parsing.
IRC::Toolkit for an extensive set of IRC-related utilities.
POE::Component::IRC if you're looking for a mature, fully-featured IRC client library.
AUTHOR
Jon Portnoy <avenj@cobaltirc.org>
Inspiration derived from POE::Component::Server::IRC::Backend and POE::Component::IRC by BINGOS, HINRIK et al.