ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/MP/Intro.pod
(Generate patch)

Comparing AnyEvent-MP/MP/Intro.pod (file contents):
Revision 1.16 by elmex, Wed Aug 26 14:02:11 2009 UTC vs.
Revision 1.17 by elmex, Thu Aug 27 15:50:50 2009 UTC

8 8
9What kind of messages? Well, basically a message here means a list of Perl 9What kind of messages? Well, basically a message here means a list of Perl
10strings, numbers, hashes and arrays, anything that can be expressed as a 10strings, numbers, hashes and arrays, anything that can be expressed as a
11L<JSON> text (as JSON is used by default in the protocol). 11L<JSON> text (as JSON is used by default in the protocol).
12 12
13It's custom in L<AnyEvent::MP> to have a string which describes the type of the
14message as first element (this is called a I<tag> in L<AnyEvent::MP>), as some
15API functions (C<rcv>) support matching it directly. So supposedly you want to
16send a ping message with your current time to something, this is how such a
17message might look like (in Perl syntax):
18
19 ['ping', 1251381636]
20
13And next you might ask: between which entities are those messages being 21And next you might ask: between which entities are those messages being
14"passed"? Physically within or between I<nodes>: a nodes is basically a 22I<passed>? They are I<passed> between I<ports>. I<ports> are just sources and
15process/program that use L<AnyEvent::MP> and can run either on the same or 23destinations for messages. How do these ports relate to things you know? Well,
16different hosts. 24each I<port> belongs to a I<node>, and a I<node> is just the UNIX process that
25runs your L<AnyEvent::MP> application.
17 26
18To make this more manageable, every node can contain any number of 27Each I<node> is distinguished from other I<nodes> running on the same host or
19I<ports>: Ports are ultimately the receivers of your messages. 28multiple hosts in a network by it's I<node ID>. A I<node ID> can be manually
29assigned or L<AnyEvent::MP> will assign one it self for you.
20 30
31So, you might want to visualize it like this (setup is two nodes: Node C<A> (in
32UNIX process 7066) with ports C<ABC> and C<DEF> and C<B> (in UNIX process 8321)
33with ports C<FOO> and C<BAR>).
34
35
36 |- PID: 7066 -| |- PID: 8321 -|
37 | | | |
38 | Node ID: A | | Node ID: B |
39 | | | |
40 | Port ABC =|= <----\ /-----> =|= Port FOO |
41 | | X | |
42 | Port DEF =|= <----/ \-----> =|= Port BAR |
43 | | | |
44 |-------------| |-------------|
45
46The strings for the ports here are just for illustrative purposes. Even if in
47reality I<ports> in L<AnyEvent::MP> are also identified by strings they can't
48be choosen manually and are assigned randomly. These I<port ids> should also
49not be used directly for other purposes than refering to an endpoint for
50messages.
51
52The next sections will explain the API of L<AnyEvent::MP>. First the API is
53layed out by simple examples. Later some more complex idioms are introduced,
54which are maybe useful to solve some realworld purposes.
55
21In this tutorial I'll show you how to write a simple chat server based on 56# In this tutorial I'll show you how to write a simple chat server based on
22L<AnyEvent::MP>. This example is used because it nicely shows how to organise a 57# L<AnyEvent::MP>. This example is used because it nicely shows how to organise a
23simple application, but keep in mind that every node trusts any other, so this 58# simple application, but keep in mind that every node trusts any other, so this
24chat cannot be used to implement a real public chat server and client system, 59# chat cannot be used to implement a real public chat server and client system,
25but it can be used to implement a distributed chat server for example. 60# but it can be used to implement a distributed chat server for example.
61
62=head1 Passing Your First Message
63
64As start lets have a look at the messaging API. The next example is just a
65demo to show the basic elements of message passing with L<AnyEvent::MP>.
66It shout just print: "Ending with: 123". So here the code:
67
68 use AnyEvent;
69 use AnyEvent::MP;
70
71 my $end_cv = AnyEvent->condvar;
72
73 my $port = port;
74
75 rcv $port, test => sub {
76 my ($data) = @_;
77 $end_cv->send ($data);
78 };
79
80 snd $port, test => 123;
81
82 print "Ending with: " . $end_cv->recv . "\n";
83
84It already contains most functions of the essential L<AnyEvent::MP> API.
85
86First there is the C<port> function which will create a I<port> and will return
87it's I<port id>.
88
89That I<port id> can be used to send and receive messages. That I<port id> is a
90simple string and can be safely passed to other I<nodes> in the network to
91refer to that specific port (usually used for RPC, where you need to
92tell the other end which I<port> to send the reply to).
93
94Next function is C<rcv>:
95
96 rcv $port, test => sub { ... };
97
98It sets up a receiver callback on a specific I<port> which needs to be
99specified as the first argument. The next argument, in this example C<test>, is
100a I<tag> match. This means that whenever a message, with the first element
101being the string C<tag>, is received the callback is called with the remaining
102parts of that message.
103
104Messages can be send with the C<snd> function, which looks like this in the
105example above:
106
107 snd $port, test => 123;
108
109This will send the message C<['test', 123]> to the I<port> with the I<port id>
110in C<$port>. The receiver got a I<tag> match on C<test> and will call the
111callback with the first argument being the number C<123>.
112
113That callback then just passes that number on to the I<condition variable>
114C<$end_cv> which will then pass the value to the print. But I<condition
115variables> are out of the scope of this tutorial. So please consult the
116L<AnyEvent::Intro> about them.
117
118But passing messages inside one process is boring, but before we can continue
119and take the next step to interprocess message passing we first have to make
120sure some things have been setup.
26 121
27=head1 System Requirements and System Setup 122=head1 System Requirements and System Setup
28 123
29Before we can start we have to make sure some things work on your 124Before we can start with real IPC we have to make sure some things work on your
30system. 125system.
31 126
32You should of course first make sure that L<AnyEvent> and L<AnyEvent::MP>
33are installed. But how to do that is out of scope of this tutorial.
34
35Then we have to setup a I<shared secret>: for two L<AnyEvent::MP> nodes to 127First we have to setup a I<shared secret>: for two L<AnyEvent::MP> I<nodes> to
36be able to communicate with each other and authenticate each other it is 128be able to communicate with each other and authenticate each other it is
37necessary to setup the same I<shared secret> for both of them (or use TLS 129necessary to setup the same I<shared secret> for both of them (or use TLS
38certificates). 130certificates).
39 131
40The easiest way is to set this up is to use the F<aemp> utility: 132The easiest way is to set this up is to use the F<aemp> utility:
41 133
42 aemp gensecret 134 aemp gensecret
43 135
44This creates a F<$HOME/.perl-anyevent-mp> config file and generates a 136This creates a F<$HOME/.perl-anyevent-mp> config file and generates a random
45random shared secret. You can copy this file to any other system and then 137shared secret. You can copy this file to any other system and then communicate
46communicate with it. You can also select your own shared secret (F<aemp 138over the network (via TCP) with it. You can also select your own shared secret
47setsecret>) and for increased security requirements you can even create 139(F<aemp setsecret>) and for increased security requirements you can even create
48a TLS certificate (F<aemp gencert>), causing connections to not just be 140a TLS certificate (F<aemp gencert>), causing connections to not just be
49authenticated, but also to be encrypted. 141authenticated, but also to be encrypted.
50 142
51Connections will only be successful when the nodes that want to connect to 143Connections will only be successful when the I<nodes> that want to connect to
52each other have the same I<shared secret> (or successfully verify the TLS 144each other have the same I<shared secret> (or successfully verify the TLS
53certificate of the other side). 145certificate of the other side).
54 146
55B<If something does not work as expected, and for example tcpdump shows 147B<If something does not work as expected, and for example tcpdump shows
56that the connections are closed almost immediately, you should make sure 148that the connections are closed almost immediately, you should make sure
57that F<~/.perl-anyevent-mp> is the same on all hosts/user accounts that 149that F<~/.perl-anyevent-mp> is the same on all hosts/user accounts that
58you try to connect with each other!> 150you try to connect with each other!>
59
60=head1 Passing Your First Message
61
62As start lets have a look at the messaging API. The next example is just a
63demo to show the basic elements of message passing with L<AnyEvent::MP>.
64It shout just print: "Ending with: 123". So here the code:
65
66 use AnyEvent;
67 use AnyEvent::MP;
68
69 initialise_node;
70
71 my $end_cv = AnyEvent->condvar;
72
73 my $port = port;
74
75 rcv $port, test => sub {
76 my ($data) = @_;
77 $end_cv->send ($data);
78 };
79
80 snd $port, test => 123;
81
82 print "Ending with: " . $end_cv->recv . "\n";
83
84It already contains lots of the API that we are going to use. First there
85is C<initialise_node>, which will initialise the L<AnyEvent::MP> node for that
86process.
87
88Next there is the C<port> function which will create a I<port id> for us, where
89we can wait for messages and send messages to. The port id is a simple string,
90which acts as identifier for a port, with the form C<noderef#portname>. The
91I<noderef> is basically a string that refers to the node and also contains
92enough information to contact the node from the outside. The I<portname> is
93usually just a random string.
94
95Next the call to C<rcv> sets up a receiver callback. The first element in
96every message is usually denoting it's I<type> or I<tag>. Which should be a
97simple string, the second argument to C<rcv> lets us match the tag of a
98message. If it matches, the callback will be called, with the remaining
99elements of the message as arguments.
100
101C<snd> sends a message. The message consists of two elements: The string
102C<'test'> and the number C<123>.
103
104The message arrives in the callback we setup with C<rcv> and will trigger the
105condition variable C<$end_cv> to deliver the result value and end the program.
106 151
107=head1 The Chat Client 152=head1 The Chat Client
108 153
109OK, lets start by implementing the "frontend" of the client. We will 154OK, lets start by implementing the "frontend" of the client. We will
110develop the client first and postpone the server for later, as the most 155develop the client first and postpone the server for later, as the most

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines