Hue-Bond has asked for the wisdom of the Perl Monks concerning the following question:

This is going to be long, since I tried several things before posting.

X problem

The infamous CB<->IRC connection. My approach is different, though:

I asked about this in the CB some days ago. I was told not to reinvent the wheel and ask Petruchio; did it but got no answer from him. tye warned me about violating pair.com's terms of service but, because the traffic is going to be the same, I don't think this will break any rule. Since this is a different way to do it (a different wheel, so to speak), I went on.

I want to mimic the way Bitlbee works. It runs a local IRC server as a frontend, and has backends to many IM networks. That way, users can chat on IRC and IM using only one client. From the end user point of view, IRC networks are reachable at irc.whatever.tld as always, while IM networks are all at localhost:6667, and Bitlbee takes care of the rest. The IRC server doesn't link with any other, the IM conversations aren't made public.

So I thought that integrating the Unix text-mode CB Client with POE::Component::Server::IRC would make it. Input from PM would be submitted to the IRC server, and messages coming from the server would be posted back to PM.

Y problem

When I send a message to myself on the IRC server, of course a PRIVMSG event is dispatched (the event is exactly called ircd_client_privmsg). There's a function taking care of this (ircd_client_message) but I need to additionally run some own code in order to send the message to PM. The key is: seemingly you cannot tell PoCo::Server::IRC "Hey!, warn me whenever that event occurs!".

Base code

This is the base code I'm playing with. It's virtually identical to the code supplied in the documentation:

#!/usr/bin/perl use warnings; use strict; use POE; use POE::Component::Server::IRC; my $pocosi = POE::Component::Server::IRC->spawn (Alias => 'ircd', Debu +g => 1); POE::Session->create ( inline_states => { _start => \&test_start, _stop => \&test_stop, }, heap => { Obj => $pocosi }, ); $poe_kernel->run(); exit 0; sub test_start { my ($kernel,$heap) = @_[KERNEL,HEAP]; $kernel->post ( 'ircd' => 'register' ); $kernel->post ( 'ircd' => 'configure' => { Auth => 1, AntiFlood => + 1 } ); $kernel->post ( 'ircd' => 'add_i_line' => { IPMask => '*', Port => + 6667 } ); $kernel->post ( 'ircd' => 'add_operator' => { UserName => 'Flibble +', Password => 'letmein' } ); $kernel->post ( 'ircd' => 'add_listener' => { Port => 6667 } ); $kernel->post ( 'ircd' => 'set_motd' => [ 'This is an experimental + server', 'Testing POE::Component::Server::IRC', 'Enjoy!' ] ); } sub test_stop { print "Server stopped\n"; }

First attempt

The first things I tried were related to the way the POE::Session was being created:

POE::Session->create ( inline_states => { _start => \&test_start, _stop => \&test_stop, # ircd_client_privmsg => \&POE::Component::Server::IRC::hue_priv +msg_handler, ## 1 }, # object_states => [ $pocosi => { ircd_client_privmsg => 'hue_privms +g_handler' },], ## 2 # package_states => [ 'POE::Component::Server::IRC' => { ircd_client +_privmsg => 'hue_privmsg_handler' },], ## 3 heap => { Obj => $pocosi }, );

I played with every one of those commented lines without success. I created the sub in the package POE::Component::Server::IRC and not in main because that's the way #2 works, and it does no harm to the rest of the module. It never gets called. But if I add this to test_start:

$kernel->post ( 'ircd', 'ircd_client_privmsg', 'test1'); $kernel->delay ( 'ircd_client_privmsg', 2, 'test2');

Then my code finally runs one time. It doesn't matter which of the three approaches I try, it works with all. The function gets the parameter 'test2'. If I turn on POE::Kernel tracing (using sub POE::Kernel::TRACE_DEFAULT() {1} as documented) I can see that that event is dispatched to session 5, while all other events go to session 2. Session 5 is the one I'm playing with, session 2 is created inside the module code. This does not help, because I can't get the session 2's ID.

Second attempt

Let's remove the $kernel->delay line and the three ones added to the session constructor, leaving only the $kernel->post one, since this sends events to the session that matters. Next plan deals with overriding POE::Component::Server::IRC::ircd_client_message with my own function, and then call the original from there. Tried this:

my $pocosi_ircd_client_message = \&POE::Component::Server::IRC::ircd_c +lient_message; sub POE::Component::Server::IRC::ircd_client_message { print "got in!\n"; # $pocosi_ircd_client_message->(@_); }

This way my code runs. Then I uncomment the line that calls the original sub and surprise! It's my sub which is called again, in an infinite fashion :). Of course, when I redefine the function, I don't get a copy so $pocosi_ircd_client_message keeps "pointing" to the same place. The original function is lost. If I could take a copy of it, that would be resolved.

So...

Well, I'm stuck with this. Maybe the solution has to do with implementing that kind of "Hey!" messages I talked about at the beginning. Or maybe I could subclass the module and define my own spawn method, which I could take the ID of, and play with that solution I mentioned earlier. Or maybe... ideas welcome!

--
David Serrano

Replies are listed 'Best First'.
Re: PoCo::Server::IRC: getting code of mine executed on event
by bingos (Vicar) on Jul 03, 2006 at 08:56 UTC

    Hi,

    I'm the author of POE::Component::Server::IRC, no please don't hit me >:o)

    I'll give a little bit of background. I started coding POE::Component::Server::IRC nearly two years ago now, mainly after I realised that POE::Component::IRC::Service just wasn't going to do what I wanted it to do. The first fruits of that labour were version 0.3 which is on CPAN.

    This version is okay, but it has a number of problems with it, mainly that it is a monolithic monster that doesn't lend itself to being extended, there was no server-to-server protocol support and it didn't have 'hooks' so one could write services.

    So I released what I had as there was some interest in the POE community in what I had been working on.

    Time passed, I had other stuff to do, mainly working on POE::Component::IRC.

    I went back to the drawing board and redesigned POE::Component::Server::IRC from the ground-up. It's modular, extensible, has server-to-server protocol support (TSora5), hooks for writing IRC services and supports a plugin system that looks surprisingly like POE::Component::IRC's >:o)

    The upshot of all this rambling is that version 0.99 of POE::Component::Server::IRC will be hitting CPAN in the next week or so (I am currently finishing off writing the documentation and testing against a four hybrid ircd network).

    In the meantime if you want, you can harass me either via my listed CPAN email contact address or via IRC: I am on Quakenet, EFNet, Freenode and MAGnet.

    CB <-> IRC has been much mooted and incidently was one of reasons I started the POE::Component::Server::IRC rewrite, after someone pointed out how shit version 0.3 was for doing this kind of thing.

    Watch this space

    BinGOs
    "If it isn't broke, you haven't hit it hard enough"