… | |
… | |
320 | without listeners, but they can still talk to all other nodes. For this |
320 | without listeners, but they can still talk to all other nodes. For this |
321 | example, as well as in many cases in the real world, we can live with this |
321 | example, as well as in many cases in the real world, we can live with this |
322 | restriction, and this makes it easier to avoid DNS (assuming your setup is |
322 | restriction, and this makes it easier to avoid DNS (assuming your setup is |
323 | broken, eliminating one potential problem :). |
323 | broken, eliminating one potential problem :). |
324 | |
324 | |
|
|
325 | Whee, setting up nodes can be complicated at first, but you only have to |
|
|
326 | do it once per network, and you can leave this boring task to the admins |
|
|
327 | or end-users that want to use your stuff :) |
|
|
328 | |
325 | =head3 Registering The Receiver |
329 | =head3 Registering The Receiver |
326 | |
330 | |
327 | Ok, where were we. We now discussed the basic purpose of L<AnyEvent::MP::Global> |
331 | Coming back to our example, we have now introduced the basic purpose of |
328 | and initialise_node with it's relations to profiles. We also setup our profiles |
332 | L<AnyEvent::MP::Global> and C<initialise_node> and its use of profiles. We |
329 | for later use and now have to continue talking about the receiver example. |
333 | also set up our profiles for later use and now we will finally continue |
|
|
334 | talking about the receiver. |
330 | |
335 | |
331 | Lets look at the next undiscussed line(s) of code: |
336 | Let's look at the next line(s): |
332 | |
337 | |
333 | my $port = port; |
338 | my $port = port; |
334 | AnyEvent::MP::Global::register $port, "eg_receivers"; |
339 | AnyEvent::MP::Global::register $port, "eg_receivers"; |
335 | |
340 | |
336 | The C<port> function already has been discussed. It just creates a new I<port> |
341 | The C<port> function has already been discussed. It simply creates a new |
337 | and gives us the I<port id>. Now to the C<register> function of |
342 | I<port> and returns the I<port ID>. The C<register> function, however, |
338 | L<AnyEvent::MP::Global>: The first argument is a I<port id> that we want to add |
343 | is new: The first argument is the I<port ID> that we want to add to a |
339 | to a I<global group>, and it's second argument is the name of that I<global |
344 | I<global group>, and its second argument is the name of that I<global |
340 | group>. |
345 | group>. |
341 | |
346 | |
342 | You can choose that name of such a I<global group> freely, and it's purpose is |
347 | You can choose the name of such a I<global group> freely (prefixing your |
|
|
348 | package name is highly recommended!). The purpose of such a group is to |
343 | to store a set of I<port ids>. That set is made available throughout the whole |
349 | store a set of I<port IDs>. This set is made available throughout the |
344 | L<AnyEvent::MP> network, so that each node can see which ports belong to that |
350 | whole L<AnyEvent::MP> network, so that each node can see which ports |
345 | group. |
351 | belong to that group. |
346 | |
352 | |
347 | The sender will later look for the ports in that I<global group> and send |
353 | Later we will see how the sender looks for the ports in this I<global |
348 | messages to them. |
354 | group> to send messages to them. |
349 | |
355 | |
350 | Last step in the example is to setup a receiver callback for those messages |
356 | The last step in the example is to set up a receiver callback for those |
351 | like we have discussed in the first example. We again match for the I<tag> |
357 | messages, just as was discussed in the first example. We again match |
352 | C<test>. The difference is just that we don't end the application after |
358 | for the tag C<test>. The difference is that this time we don't exit the |
353 | receiving the first message. We just infinitely continue to look out for new |
359 | application after receiving the first message. Instead we continue to wait |
354 | messages. |
360 | for new messages indefinitely. |
355 | |
361 | |
356 | =head2 The Sender |
362 | =head2 The Sender |
357 | |
363 | |
358 | Ok, now lets take a look at the sender: |
364 | Ok, now let's take a look at the sender code: |
359 | |
365 | |
360 | #!/opt/perl/bin/perl |
|
|
361 | use AnyEvent; |
366 | use AnyEvent; |
362 | use AnyEvent::MP; |
367 | use AnyEvent::MP; |
363 | use AnyEvent::MP::Global; |
368 | use AnyEvent::MP::Global; |
364 | |
369 | |
365 | initialise_node "eg_simple_sender"; |
370 | initialise_node "eg_simple_sender"; |
… | |
… | |
373 | for @$ports; |
378 | for @$ports; |
374 | }); |
379 | }); |
375 | |
380 | |
376 | AnyEvent->condvar->recv; |
381 | AnyEvent->condvar->recv; |
377 | |
382 | |
378 | It's even less code. The C<initialise_node> is known now from the receiver |
383 | It's even less code. The C<initialise_node> serves the same purpose as in |
379 | above. As discussed in the section where we setup the profiles we configure |
384 | the receiver, we just specify a different profile, the profile we set up |
380 | this application to use the I<profile> C<eg_simple_sender>. |
385 | without the binds. |
381 | |
386 | |
382 | Next we setup a timer that repeatedly calls this chunk of code: |
387 | Next we set up a timer that repeatedly (every second) calls this chunk of |
|
|
388 | code: |
383 | |
389 | |
384 | my $ports = AnyEvent::MP::Global::find "eg_receivers" |
390 | my $ports = AnyEvent::MP::Global::find "eg_receivers" |
385 | or return; |
391 | or return; |
386 | |
392 | |
387 | snd $_, test => time |
393 | snd $_, test => time |
388 | for @$ports; |
394 | for @$ports; |
389 | |
395 | |
390 | The new function here is the C<find> function of L<AnyEvent::MP::Global>. It |
396 | The only new function here is the C<find> function of |
391 | searches in the I<global group> named C<eg_receivers> for ports. If none are |
397 | L<AnyEvent::MP::Global>. It searches in the global group named |
392 | found C<undef> is returned and we wait for the next time the timer fires. |
398 | C<eg_receivers> for ports. If none are found, it returns C<undef>, which |
|
|
399 | makes our code return instantly and wait for the next round, as nobody is |
|
|
400 | interested in our message. |
393 | |
401 | |
394 | In case the receiver application has been connected and the newly added port by |
402 | As soon as the receiver application has connected and the information |
395 | the receiver has propagated to the sender C<find> returns an array reference |
403 | about the newly added port in the receiver has propagated to the sender |
396 | that contains the I<port id> of the receiver I<port(s)>. |
404 | node, C<find> returns an array reference that contains the I<port ID> of |
|
|
405 | the receiver I<port(s)>. |
397 | |
406 | |
398 | We then just send to every I<port> in the I<global group> a message consisting |
407 | We then just send a message with a tag and the current time to every |
399 | of the I<tag> C<test> and the current time in form of a UNIX timestamp. |
408 | I<port> in the global group. |
400 | |
409 | |
401 | And thats all. |
410 | =head3 Multiple Receivers |
|
|
411 | |
|
|
412 | You can even run multiple receivers - the only problem is that they will |
|
|
413 | use the same node ID. To avoid this problem, you can either not specify a |
|
|
414 | profile name at all and rely on DNS and your POSIX node name, or you can |
|
|
415 | use a special feature called "anonymous nodes": |
|
|
416 | |
|
|
417 | aemp profile eg_simple_receiver setnodeid anon/ |
|
|
418 | |
|
|
419 | The special name C<anon/> will be replaced by a random string each time |
|
|
420 | the node starts. This way you can start many receivers (they do not bind |
|
|
421 | on a TCP port, so cnanot collide with each other), and all of them will |
|
|
422 | receive the central time signal. |
|
|
423 | |
|
|
424 | That's all for now - next time we will teach you about monitoring by |
|
|
425 | writing a simple chat client and server :) |
402 | |
426 | |
403 | =head1 SEE ALSO |
427 | =head1 SEE ALSO |
404 | |
428 | |
405 | L<AnyEvent> |
429 | L<AnyEvent> |
406 | |
430 | |