POEx::IRC::Backend - IRC client or server backend


  use POE;
  use POEx::IRC::Backend;

    package_states => [
      main => [ qw/
      / ],

  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:
      bindaddr => $addr,
      port     => $port,

    # Connect to a remote endpoint:
      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 ...


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).



Retrieve the POE::Session ID for the backend's registered controller.

Predicate: has_controller


A HASH of active Connector objects, keyed on their wheel ID.


A POE::Filter::Stackable instance consisting of the current "filter_irc" stacked with "filter_line" (at the time the attribute is built).


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),


A POE::Filter::Line instance.


HASH of active Listener objects, keyed on their wheel ID.


Returns the backend's session ID.


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.


HASH of actively connected wheels, keyed on their wheel ID.



  my $backend = POEx::IRC::Backend->spawn(
    ## Optional, needed for SSL-ified server-side sockets
    ssl_opts => [

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.


    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.


    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).


      listener => $listener_id,

    ## or via addr, port, or combination thereof:
      addr => '',
      port => 6667,

Removes a listener and clears its wheel attribute; the socket shuts down when the POE::Wheel::SocketFactory wheel goes out of scope.


  $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".


Like "disconnect", but attempt to destroy the wheel immediately (without waiting for a buffer flush).


      prefix  => $prefix,
      params  => [ @params ],
      command => $cmd,

  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'";
        { prefix => $prefix, params => [ @params ], command => $cmd },


Returns true if POE::Component::SSLify was successfully loaded.


Returns true if POE::Filter::Zlib::Stream was successfully loaded.

  $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.

  $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.

  $backend->unset_compressed_link( $conn_id );

Remove POE::Filter::Zlib::Stream from the connection's filter stack.

Received events


  $poe_kernel->post( $backend->session_id,

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.


Event interface to create_connector -- see "Methods"


Event interface to create_listener -- see "Methods"


Event interface to remove_listener -- see "Methods"


Event interface to /send -- see "Methods"


Disconnect all wheels and clean up.

Dispatched events

These events are dispatched to the controller session; see "register".


Dispatched when a connection wheel has had a compression filter added.

$_[ARG0] is the connection's POEx::IRC::Backend::Connect.


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


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.


Dispatched when a Connector has established a connection to a peer.

$_[ARG0] is the POEx::IRC::Backend::Connect for the connection.


Dispatched when a connection wheel has been cleared.

$_[ARG0] is the connection's POEx::IRC::Backend::Connect with wheel() cleared.


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.


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.


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.


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


Dispatched when a Listener has been removed.

$_[ARG0] is the POEx::IRC::Backend::Listener object.


Dispatched when a "register" event has been successfully received, as a means of acknowledging the controlling session.

$_[ARG0] is the Backend's $self object.


Probably lots. Please report them via RT, e-mail, IRC (, or GitHub (








POEx::IRC::Client::Lite for an experimental IRC client library using this backend. 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.


Jon Portnoy <>

Inspiration derived from POE::Component::Server::IRC::Backend and POE::Component::IRC by BINGOS, HINRIK et al.