NAME
POE::Component::Lightspeed - The romping grounds of IKC2
SYNOPSIS
use
POE;
# Create a new client session
POE::Component::Lightspeed::Client->spawn(
'KERNEL'
=>
'testbox'
,
'ADDRESS'
=>
'192.168.1.100'
,
);
# Create our own session to communicate with Lightspeed
POE::Session->create(
inline_states
=> {
_start
=>
sub
{
$_
[KERNEL]->alias_set(
'mysession'
);
# Yes, a better way to "monitor" Lightspeed is on the way...
# For now, just give POE some time to connect
$_
[KERNEL]->delay_set(
'do_stuff'
, 5 );
# Demonstration of Lightspeed hackery
$_
[KERNEL]->delay_set(
'confused'
, 1 );
},
'do_stuff'
=>
sub
{
# Perfect
# Wrong
#$_[KERNEL]->post( 'poe://otherbox/mysession', 'ping', 'how are you?' );
},
'pong'
=>
sub
{
"Received 'pong' from "
.
$_
[SENDER]->ID .
"\n"
;
},
'confused'
=>
sub
{
# Is this a lightspeed session?
if
(
$_
[SENDER]->is_lightspeed ) {
# Yay!
"Received Lightspeed request from: '"
;
}
else
{
"Received regular request from: '"
;
}
$_
[SENDER]->ID .
"' State '"
.
$_
[CALLER_STATE] .
"' File '"
.
$_
[CALLER_FILE] .
"' Line '"
.
$_
[CALLER_LINE] .
"'\n"
;
},
);
--------
use
POE;
# Create a new server session
POE::Component::Lightspeed::Server->spawn(
'KERNEL'
=>
'otherbox'
,
'ADDRESS'
=>
'192.168.1.100'
,
);
# Create our own session to listen for requests from Lightspeed
POE::Session->create(
inline_states
=> {
_start
=>
sub
{
$_
[KERNEL]->alias_set(
'mysession'
);
},
'ping'
=>
sub
{
"Received 'ping' from "
.
$_
[SENDER]->ID .
" -> "
.
$_
[ARG0] .
"\n"
;
# Perfect
$_
[KERNEL]->post(
$_
[SENDER],
'pong'
,
'wassup!'
);
$_
[KERNEL]->post(
$_
[SENDER]->ID,
'pong'
,
'wazzup!'
);
# Wrong
#$_[KERNEL]->post( "$_[SENDER]", 'ping', 'wassup!' );
# Demonstration of Lightspeed hackery
},
},
);
ABSTRACT
This module aims to
connect
POE kernels into a network, a
"botnet"
of sorts.
Furthermore, the venerable IKC is now under design & development towards IKC2.
Think of this module as a playground
for
IKC2 ideas, so don
't do any serious development around this unless I tell you it'
s ok!
CHANGES
0.03
- A lot of internal cleanups and tweaks
- Added the Introspection module
0.02
- Documentation cleanups ( I am always a POD newbie )
0.01
- Initial release to public :)
DESCRIPTION
In the Lightspeed world, you have either a server or a client. Obviously, the clients connect to servers. In order for server kernels to connect to other kernels, you can run a client and a server session in the same process.
Please familiarize yourself with the concepts of IKC, especially it's "destination specifier" stuff.
The big difference between Lightspeed and IKC is that a lot of the bookkeeping stuff has been automated. You no longer have to publish sessions, nor register for remote sessions. Sending messages is a snap, using the normal $_[KERNEL]->post() interface everyone is accustomed to, instead of sending to a session to do the work.
Lightspeed goes a step beyond IKC, it does not create "proxy" sessions to relay data back to the remote kernel. Instead, it hacks into POE::Kernel, POE::Session, and POE::Resource::Events to get them to recognize the destination specifiers and act upon them.
DESTINATION SPECIFIER
The IKC destination specifier has been expanded a little, now you can send to multiple kernels/sessions at the same time.
'poe://kernel1,kernel2/session1,session2/state'
Furthermore, the special character '*' signifies "broadcast"
Also, it's possible to pass the specifier as an arrayref or hashref
ARRAYREF:
[ kernel, session, state ]
HASHREF:
{
'KERNEL'
=> kernel,
'SESSION'
=> session,
'STATE'
=> state,
}
POST
To post to a remote kernel, there are a few formats allowed.
$kernel
->post(
$_
[SENDER],
'state'
,
@args
);
# Will work nicely too
$kernel
->post(
$_
[SENDER]->ID,
'state'
,
@args
);
# Ditto
$kernel
->post( [
qw( kernel session state )
],
@args
);
# Alternate method of supplying the specifier
$kernel
->post(
$_
[SENDER],
$_
[CALLER_STATE],
@args
)
# Yes, Lightspeed supplies this information too!
These ways will fail horrendously:
$kernel
->post(
$_
[SENDER],
@args
);
# No, Lightspeed will not automatically send it back to the originating kernel/session/state!
$kernel
->post(
$_
[SENDER]->ID,
@args
);
# Ditto.
$kernel
->post(
$_
[SENDER]->ID .
'state'
,
@args
);
# This will fail if $_[SENDER] is not a remote kernel, but WILL WORK!
CALL
The concept of a call() cannot be really applied to remote kernels, so you have to supply a "RSVP" destination, the place where the resulting data from the call() should go.
To call a remote kernel, there are a few formats allowed.
$kernel
->call(
'poe://kernel/session/state'
,
'poe://kernel/session/state'
,
@args
);
# The "Lightspeed" way to do it
$kernel
->call(
$_
[SENDER],
'state'
, [
qw( kernel session state )
],
@args
);
# Alternate method of supplying the specifier
$kernel
->call(
$_
[SENDER],
$_
[CALLER_STATE],
'poe://kernel/session/state'
,
@args
);
# Yes, Lightspeed supplies this information too!
These ways will fail horrendously:
$kernel
->call(
$_
[SENDER]->ID .
'state'
,
'poe://kernel/session/state'
,
@args
);
# This will fail if $_[SENDER] is not a remote kernel, but WILL WORK!
Lightspeed Extras
Being super-friendly as it is, Lightspeed gives the programmer a few extras to make their life easier!
The predefined event fields will give you the correct information:
- SENDER
- CALLER_STATE
- CALLER_FILE
- CALLER_LINE
A few methods
has
been added to POE::Session (
$_
[SENDER] )
- is_lightspeed
It returns true
if
the calling session is on a remote kernel, false otherwise
These methods are valid only
if
is_lightspeed() returns true:
- remote_kernel
Returns the name of the remote kernel
- remote_session
Returns the name of the remote session
- remote_state
Returns the name of the remote state
- remote_file
Returns the filename that initiated this request
- remote_line
Returns the line number that initiated this request
The
$session
->ID method returns the following string. This can be used freely as a session specifier, but you still
have to supply the state. So, it
's very possible to do stuff like $_[SENDER]->ID . '
state' and get the right specifier
to supply.
Lightspeed checks the POE Version and matches the appropriate hackery, so
if
you have an unsupported version
of POE, it won
't work because I don'
t want to totally screw up POE by using the wrong data. If there's a reason you
absolutely must have support
for
POE version X, let me know and I can hack it up.
Postbacks/Callbacks work properly
with
$_
[SENDER], even
when
it is a remote kernel :)
GOTCHAS
- If you
're using a subclass of POE::Session that does not inherit from POE::Session, the lightspeed hackery won'
t work!
- The versions of the serializer on both the client/server MUST be the same, Storable is very picky about this!
- A client cannot
connect
to a server in the same process
- Every kernel name in the network must be unique, the
default
POE::Kernel->ID is useful
for
this
- This is not a spanning tree network, that means a cyclic network is allowed. This is the opposite of IRC networks.
Spanning Tree:
A - B - D
|
C
Cyclic network:
/------\
A - B - C - D
\------/
- Unlike IKC, there is
no
need to
"publish"
sessions
- You post events through the POE::Kernel instance, not to a special session
- The characters
'*'
,
'/'
, and
','
is not allowed in kernel names and session aliases
- Keep in mind,
when
you are sending objects, that the appropriate modules are loaded in both the sender + receiver
KNOWN BUGS / TODO LIST
- 2 Clients connecting at the same
time
screws up the routing
system
, I'm working on it...
- Argument parsing isn't as strict as it should be, and funky things will be allowed, like:
- As of now, Lightspeed will silently drop messages destined towards unknown kernels/sessions
- Addition of a
"monitor"
system
where you register
for
callbacks whenever specific things happen:
- Client
connect
/disconnect
- Messages leaving/arriving their destinations
- General debugging junk
- Addition of an
"authentication"
system
to filter incoming messages
- Allow post/call from specific kernels/sessions/states
- Refuse clients meeting certain criteria
- Adding SSL to the whole picture
- Adding the
local
ip/port to
bind
to
for
clients
- Creating the ClientLite module, similar to the one found in IKC
- Would be nice
for
the Lightspeed router to
"weigh"
specific links and adjust priority to accomodate lag/load
- More documentation!
EXPORT
The only exportable stuff is in POE::Component::Lightspeed::Constants which isn't for general consumption.
SEE ALSO
POE::Component::Lightspeed::Server
POE::Component::Lightspeed::Client
POE::Component::Lightspeed::Introspection
AUTHOR
Apocalypse <apocal@cpan.org>
COPYRIGHT AND LICENSE
Copyright 2005 by Apocalypse
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.