IKC stands for "Inter-Kernel Communication" and is used to pass events between POE processes. The ClientLite library allows non-POE programs to interact with POE-based services.
In this example, the server adds up a list of number and returns their sum. The client sends such a list and prints the result.
Summing : 8 6 7 5 3 0 9 The sum is: 38
Here is the server. As usual, the comments make it look longer than it actually is.
#!/usr/bin/perl use warnings; use strict; use lib qw(blib/lib blib/arch); use POE qw(Session); use POE::Component::IKC::Server; use POE::Component::IKC::Specifier; # Create an IKC server. It runs as a separate session, and does # message passing for us. POE::Component::IKC::Server->spawn( port => 31338, name => 'AppServer', ); # Create a session that will be accessible through an IKC network. POE::Session->create( inline_states => { _start => \&service_start, calc_sum => \&service_calc_sum, did_something => \&service_response, } ); # Run, server, run! POE::Kernel->run(); exit 0; # Start the service. Set up an alias, which is our service's name. # Call IKC to publish the service and some public events. sub service_start { my ($kernel, $heap) = @_[KERNEL, HEAP]; my $service_name = "application"; $kernel->alias_set($service_name); $kernel->call(IKC => publish => $service_name, ["calc_sum"]); } # Calculate the sum of the numbers in a list. We only perform minimal # data validation here, which may be a hazard in a real application. # # This service is intended for use with PoCo::IKC::ClientLite's # post_respond() method. Therefore ARG0 is special: the data given to # us is in element 0, and an RSVP identifier is in element 1. Posting # the response to the RSVP identifier will send it back to the # requester. # # However, we don't send the sum back right away. Instead, we delay a # little bit to show how you can pass data through the usual POE event # handlers before sending it back. sub service_calc_sum { my ($kernel, $heap, $request) = @_[KERNEL, HEAP, ARG0]; my ($data, $rsvp) = @$request; my $sum = 0; if (ref($data) eq "ARRAY") { $sum += $_ foreach @$data; } $kernel->delay_set(did_something => 1, $rsvp, $sum); } # After a little time, send the response back. We post the response # to the RSVP identifier. IKC matches it up to the client internally. sub service_response { my ($kernel, $heap, $rsvp, $sum) = @_[KERNEL, HEAP, ARG0, ARG1]; $kernel->call(IKC => post => $rsvp, $sum); }
Here is the client. Ditto about the comments.
#!/usr/bin/perl use warnings; use strict; use POE::Component::IKC::ClientLite; # Create an IKC client. This also establishes a connection to an IKC # server. Part of the registration process is choosing a unique name # for ourselves, which we do naively by abusing the process ID. my $name = "Client$$"; my $remote = create_ikc_client( port => 31338, name => $name, timeout => 10, ); die $POE::Component::IKC::ClientLite::error unless $remote; # We want the server to add up a list of numbers. Using # post_return(), we can send a detached event to the server and wait # for its response. The response can be delayed up to the # create_ikc_client() timeout. post_return() returns the value that # was posted back to us from service_response() in the corresponding # server example. my @numbers = qw(8 6 7 5 3 0 9); print "Summing : @numbers\n"; my $return_value = $remote->post_respond('application/calc_sum', \@numbers); die $POE::Component::IKC::ClientLite::error unless defined $return_value; print "The sum is: $return_value\n"; exit 0;