Because a signal is propagated to a session's children, and every session is a child of POE::Kernel, this line of code will broadcast a fake signal to every session:
$kernel->signal($kernel, 'FakeSignal', @parameters);
The signal is dispatched as a signal event by default. ARG0 contains "FakeSignal" so sessions know what they've received, and ARG1..$# hold @parameters.
It's possible to aim the shotgun in a general direction with POE::Kernel's sig() method. This tells POE that the calling session wants to receive "FakeSignal" signals as "fake_signal" events rather than generic "_signal" events.
$kernel->sig(FakeSignal => "fake_signal");
Each session must call sig() to rename signals for itself. ARG0 and ARG1..$#_ will hold the same values as before.
A registry can enable sessions to request broadcasted events. When sessions start, they add themselves to a global hash. They remove themselves at stop time. Finally, a broadcast() function sends events to every session in the registry.
my %session_registry; POE::Session->create( inline_states => { ..., _start => sub { ...; # Register here. $session_registry{$_[SESSION]->ID()} = $_[SESSION]->ID(); ...; }, _stop => sub { ...; # Unregister here. delete $session_registry{$_[SESSION]->ID()}; ...; }, ..., }, ); # Send an event to every registered session. sub broadcast { my ($event, @etc) = @_; foreach (keys %session_registry) { $poe_kernel->post($_, $event, @etc); } }
The idea can be refined to provide several "channels":
my $session_registry; my $session_id = $_[SESSION]->ID(); $session_registry{channel_name}->{$session_id} = $session_id; delete $session_registry{channel_name}->{$session_id}; # Send an event to every session in a channel. sub broadcast { my ($channel, $event, @etc) = @_; foreach (keys %{$session_registry{$channel}}) { $poe_kernel->post($_, $event, @etc); } }
And so on.
Maybe it should be a component?
Fletch chimes in . . .
This is very similar to the [ObserverPattern]. Of course I just read Design Patterns recently so I may just have patterns on the brane. :)
At any rate, it might make sense to define some sort of Component::BroadcastGroup. Each group would have its own alias, and register, unregister, and notify events. That seems cleaner to me than shoehorning onto the signal framework or using a lexical structure.
Apocalypse notices something...
This is very similar to POE::Component::SimpleLog, which uses the same register/unregister concepts found here :)