Beefy Boxes and Bandwidth Generously Provided by pair Networks BBQ
go ahead... be a heretic
 
PerlMonks  

POE Sending Data Between 2 simultaneous TCP connections

by Anonymous Monk
on Jun 13, 2004 at 15:37 UTC ( #363877=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Im using 2 TCP Connections, one to IRC and one to a gameserver. I want to be able to send messages between the two. On like 200 you can see how im trying to send data in one of the IRC subs to the TCP server but when doing this i get the error; Can't call method "put" on an undefined value at poe2 line 204 $_[HEAP]->{server}->put("msg $nick\@TRiNiTY\:$renmsg");    # sends message to tcp server Is there an easy way to name the first connection so i can reffer to it in other subs later on? any help is appreciated
#!/usr/bin/perl #use warnings; use strict; use POE; use POE::Component::IRC; use POE::Component::Client::TCP; use POE::Filter::Stream;; ### BEGIN REMREM ### ## RenRem Settings my $renport = 4853; # The gameserver port my $renhost = 'somehost'; # Ip/hostname of the gameserver my $renpassword = 'somepass'; # admin password ## Buffering OFF! $| = 1; # Prevents buffering problems ##renrem output settings my $reout = 'off'; ### OUTPUT STARTUP MESSAGES TO CONSOLE my $botver = 'TRiNiTY build 118'; my $botver2 = 'A lightweight Renegade admin facility.'; my $startuptime = localtime; my $uptime = $startuptime; print " [$startuptime] ### TRiNiTY RenAdmin Facility. Designed by Phil + W ;-) ###\n"; print " [$startuptime] ######\n"; print " [$startuptime] $botver Starting up...\n"; print " [$startuptime] Initializing connection to RenRem server...\n"; sub renrem_on # Connetion to RenRem POE::Component::Client::TCP->new ( RemoteAddress => $renhost, RemotePort => $renport, Connected => \&on_renconnect, ServerInput => \&on_renrecieve, Disconnected => \&on_rendisconnect, ); sub on_rendisconnect{ # Attempt to reconnect when disconnected from renrem my $tsa = localtime; #my $kernel; #$_[KERNEL]->delay( reconnect => 60 ); print " [$tsa] WARNING!:Disconnection Detected, trying to re-estab +lish communication with renrem...\n"; } sub on_renconnect { my $ts = localtime; print " [$ts] Sucessfully connected to $renhost:$renport ! +...\n"; $_[HEAP]->{server}->put($renpassword); } sub on_renrecieve { my ( $kernel, $heap, $input ) = @_[ KERNEL, HEAP, ARG0 ]; my $ts = localtime; print " [$ts] $input\n"; # NOT all input is wanted, disguard any common stings which are + not needed if($input =~ /GameSpy mode active/ || $input =~ /Id Name/ || +$input =~ /Welcome to Renegade Remote Control/ || $input =~ /Score Side Ping Address/ || $input =~ /([0-9][0 +-9][0-9]\.[0-9][0-9]\.[0-9][0-9])/ || $input =~ /GDI/ || $input =~ /Nod/ || $input =~ /Gameplay in progress/ || $input + =~ /Map :/ || $input =~ /NOD :/ || $input =~ /Gameplay Pending/ || $input =~ /Time :/ || $input =~ /Fps :/ || $inpu +t =~ /Total current bandwidth usage for players/ || $input =~ / NOD / || $input =~ /\[[0-9][0-9]\:[0-9][0-9]\ +:[0-9][0-9]\W\W(Load)\W\d\d/ || $input =~ /Total current bandwidth usage for players/ || $input =~ /\[[0-9][0-9] +\:[0-9][0-9]\:[0-9][0-9]\W\W(Load)\W\d/) { # do nothing if these pattens are matched } elsif($input =~ /\[[0-9][0-9]\:[0-9][0-9]\:[0-9][0-9]\W\W(No p +layers)/) { #Check to see if no players are in the server $kernel->post( magnet => privmsg => '#ulfserver', "Warning +: The renrem output module has been deactivated due to the server bei +ng empty at present. It can be re-enabled at a later date using the \ +!renrem \-on command." ); $reout = 'off'; } elsif($input =~ /\[[0-9][0-9]\:[0-9][0-9]\:[0-9][0-9]\W\W[^@ \ +.]/) { #otherwise output to IRC $kernel->post( magnet => privmsg => '#ulfserver', $input ) +; } else { #disguard any unmatched or unwanted patterns #$kernel->post( magnet => privmsg => '#ulfserver', $inp +ut ); } } } ######################### RENREM COMPLETED - NOW CONNECT TO IRC ###### +################################################# sub CHANNEL () { "someircchannel" } my $botver2 = 'A standalone Renegade admin facility..'; #:: IRC Settings my $ircnetwork = 'someircserver'; my $ircport = 6667; my $ircname = 'TRiNiTY-'; my $ircident = $botver; my $ircnick = 'TRiNiTY-'; my $ircmode; # Create the component that will represent an IRC network. POE::Component::IRC->new("magnet"); # Create the bot session. The new() call specifies the events the bot # knows about and the functions that will handle those events. POE::Session->new ( _start => \&bot_start, irc_001 => \&on_connect, irc_public => \&on_public, irc_msg => \&on_msg, irc_mode => \&on_mode, ); # The bot session has started. Register this bot with the "magnet" # IRC component. Select a nickname. Connect to a server. sub bot_start { my $kernel = $_[KERNEL]; my $heap = $_[HEAP]; my $session = $_[SESSION]; $kernel->post( magnet => register => "all" ); #my $nick = 'TRiNiTY-'; $kernel->post( magnet => connect => { Nick => $ircnick, Username => $ircname, Ircname => $ircident, Server => $ircnetwork, Port => $ircport, } ); } # The bot has successfully connected to a server. Join a channel. sub on_connect { $_[KERNEL]->post( magnet => join => CHANNEL ); $_[KERNEL]->post( magnet => msg => "NickServ\@services.dal.net + :IDENTIFY somepassword\r\n" ); } # Handle Private Messages to the Bot sub on_msg { my ( $kernel, $who, $where, $msg ) = @_[ KERNEL, ARG0, ARG1, ARG2 +]; my $nick = ( split /!/, $who )[0]; my $channel = $where->[0]; my $ts = localtime; print " [$ts] <$nick:$channel> $msg\n"; } # Will Handle Changes in status on the IRC channel sub on_mode { my ( $kernel, $from, $channel, $themode, $userchanged ) = @_[ KERN +EL, ARG0, ARG1, ARG2, ARG3 ]; my $fromnick = ( split /!/, $from )[0]; my $ts = localtime; print " [$ts] <$fromnick:$channel> $themode $userchanged\n"; } # The bot has received a public message. Parse it for commands, and # respond to interesting things. sub on_public { my ( $kernel, $who, $where, $msg ) = @_[ KERNEL, ARG0, ARG1, ARG2 +]; my $nick = ( split /!/, $who )[0]; my $channel = $where->[0]; my $ts = localtime; ####### Print What Was Sent to IRC to The Console ###### print " [$ts] <$nick:$channel> $msg\n"; # !Version Sent if ($msg =~ /!version/) { print " [$ts] <$channel> version request detected\n"; $kernel->post( magnet => privmsg => CHANNEL, $botver ); $kernel->post( magnet => privmsg => CHANNEL, $botver2 ); } # !broadcast Messages Sent if ($msg =~ /!broadcast/) { #retrieve the message sent my $renmsg = split(/!broadcast/, $msg); print " [$ts] <$channel> msg $nick\@TRiNiTY\: $renmsg\n"; # output + to console $kernel->post( magnet => privmsg => CHANNEL, "$nick\@TRiNiTY\: $re +nmsg\n"); #output to IRC ## HERE I WANT TO SENT THE $RENMSG FROM THE IRC CHANNEL TO THE TCP + SERVER $_[HEAP]->{server}->put("msg $nick\@TRiNiTY\: $renmsg"); # send +s message to tcp server } # !renrem sent if ($msg =~ /!renrem/) { if ($msg =~ /\-on/) { $kernel->post( magnet => privmsg => CHANNEL, "RenRem output mo +de: Activated!"); $reout = 'on'; } elsif ($msg =~ /\-off/) { $kernel->post( magnet => privmsg => CHANNEL, "RenRem output mo +de: Deactivated!"); $reout = 'off'; } elsif ($msg =~ /\-about/) { $kernel->post( magnet => privmsg => CHANNEL, "$nick: A +bout the RenRem TRiNiTY plugin \- This module allows for server messa +ges to be forwarded over the IRC chat protocol to a pool of clients a +nd provides key gameserver functionality."); } else { $kernel->post( magnet => privmsg => CHANNEL, "!renrem (usage) +< -about/-on/-off >"); } print " [$ts] RenRem output set to $reout by $nick on $channel\n" } } # Run the bot until it is done. $poe_kernel->run(); exit 0;

Edited by Chady -- added readmore tags.

Comment on POE Sending Data Between 2 simultaneous TCP connections
Select or Download Code
Re: POE Sending Data Between 2 simultaneous TCP connections
by Fletch (Chancellor) on Jun 13, 2004 at 16:31 UTC

    Each POE::Session instance has its own heap instance (that's its purpose, private storage for the session). You need to either stash the references somwhere both sessions can see (for instance a global %wheels and then use $wheel{ IRC }->put( ... )), or subclass and add a forward_msg state which would have access to the relevant heap and post that event. (Actually come to think of it I don't think you'd really need to subclass, just use $kernel->state( forward_msg => $session => 'forward_msg' ))

      Ah thanks. Could you please give me an example of how I can set the IRC component wheel so I can intergrate the code into my script.
Re: POE Sending Data Between 2 simultaneous TCP connections
by rcaputo (Chaplain) on Jun 14, 2004 at 15:05 UTC
    Im using 2 TCP Connections, one to IRC and one to a gameserver. I want to be able to send messages between the two. On like 200 you can see how im trying to send data in one of the IRC subs to the TCP server but when doing this i get the error; Can't call method "put" on an undefined value at poe2 line 204 $_[HEAP]->{server}->put("msg $nick\@TRiNiTY\:$renmsg"); # sends message to tcp server Is there an easy way to name the first connection so i can reffer to it in other subs later on?

    As (I think) Fletch mentioned, $_[HEAP] is session-scoped storage. That is, one Session instance cannot (easily) access the heap of another. Because your TCP and IRC sessions are different, they have different heaps. You can, however, name your sessions and pass messages between them.

    This change lets other sessions send messages to your TCP connection, under the name "ren".

    sub on_renconnect { my $ts = localtime; print " [$ts] Sucessfully connected to $renhost:$renport !...\n"; $_[HEAP]->{server}->put($renpassword); $_[KERNEL]->alias_set("ren"); }

    Your TCP session can probably post IRC commands directly to "magnet". That's because your POE::Component::IRC instance has its own session and alias. Your remaining problem is getting data back to "ren".

    For this, we'll set up a custom event handler in your TCP client.

    # Connetion to RenRem POE::Component::Client::TCP->new( RemoteAddress => $renhost, RemotePort => $renport, Connected => \&on_renconnect, ServerInput => \&on_renrecieve, Disconnected => \&on_rendisconnect, InlineStates => { send_data => sub { $_[HEAP]->{server}->put($_[ARG0]); }, }, );

    Now, when "ren" receives a "send_data" message, it will send some data from its own $_[HEAP]->{server}. What's left is to send that "send_data" message.

    ## HERE I WANT TO SENT THE $RENMSG FROM THE IRC CHANNEL TO THE TCP + SERVER $kernel->post(ren => send_data => "msg $nick\@TRiNiTY\: $renmsg");

    None of my code is tested, but that's the gist of it. Have fun!

    -- Rocco Caputo - http://poe.perl.org/

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://363877]
Approved by Fletch
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2014-04-21 04:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (490 votes), past polls