2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
5
<html xmlns="http://www.w3.org/1999/xhtml">
7
<title>AMP Routes</title>
15
Normally, an AMP connection is between two <code class="API"
16
base="twisted.protocols.amp">AMP</code> instances; each instance receives
17
all AMP boxes sent by the other side and handles them by interpreting
18
them as commands, responses to commands, or in some other way. This
19
typically means that the logic for handling boxes on each side of the
20
connection is completely defined by a single object. Sometimes it is
21
useful to allow multiple objects, perhaps of different types, to
22
participate in defining this logic.
26
<code>epsilon.amprouter</code> implements utilities which allow an
27
arbitrary number of objects, providers of <code>IBoxReceiver</code> (for
28
example, instances of <code>AMP</code>), to define how received AMP boxes
29
are interpreted. This is useful to multiplex unrelated <code>AMP</code>
30
instances over a single TCP connection, to split up a single AMP protocol
31
into multiple simpler protocols, and for many other purposes.
35
Readers should familiarize themselves with the following concepts in
36
order to understand all sections of this document:
42
href="http://twistedmatrix.com/projects/core/documentation/howto/clients.html">TCP
44
href="http://twistedmatrix.com/projects/core/documentation/howto/servers.html">TCP
48
<a href="http://twistedmatrix.com/projects/core/documentation/howto/defer.html">
53
Twisted <code class="API" base="twisted.protocols.amp">AMP</code>
60
When working with routes, the object primarily of interest will be a <a
61
class="API" base="epsilon.amprouter">Router</a> instance. Each AMP
62
client and server will have a <code>Router</code> instance which they can
63
use to create new routes. They will use its <code class="API"
64
base="epsilon.amprouter">Router.bindRoute</code> method to set up
65
whatever routes they require.
71
<code>epsilon.amprouter</code> does not define a command for creating new
72
routes because different applications have different requirements for how
73
new routes are set up. An application may want to negotiate about the
74
<code>IBoxReceiver</code> implementation which is associated with a
75
route, it may want to supply initial arguments to that object, it may
76
want to do version negotiation, and so on. The first thing an
77
application using routes must do, then, is to define a way to create new
78
routes. Consider the following example which allows routes to be created
79
with a <code>NewRoute</code> AMP command and associates them with a
80
parameterized <code>IBoxReceiver</code> implementation.
83
<a href="listings/amp/route_setup.py" class="py-listing">
84
Creation of new routes
88
<code>AMPRouteServerFactory.buildProtocol</code> creates new
89
<code>RoutingAMP</code> instances, each with a new <code>Router</code>.
90
The <code>Router</code> instance will become the <code>RoutingAMP</code>
91
instance's <code>boxReceiver</code> attribute. This is important for two
92
reasons. First, it allows the router to work by causing all AMP boxes
93
received from the connection to be delivered to the router to be
94
dispatched appropriately. Second, it gives the <code>RoutingAMP</code>
95
instance a reference to the <code>Router</code> instance; this is
96
necessary so that new routes can be created.
100
After creating the <code>Router</code> and <code>RoutingAMP</code>,
101
<code>buildProtocol</code> also sets up the <code>RoutingAMP</code>
102
instance to be the default receiver by binding it to the
103
<code>None</code>. All AMP boxes without routing information will be
104
delivered to the default receiver. This is important because it allows
105
the <code>NewRoute</code> command to be handled by the
106
<code>RoutingAMP</code> instance.
110
<code>RoutingAMP</code>'s <code>NewRoute</code> responder uses
111
<code>self.boxReceiver</code>, the <code>Router</code> instance provided
112
by the factory, to <em>bind</em> the return value of
113
<code>self.factory.routeProtocol()</code> to a new route. Then, it
114
connects the route to the identifier specified in the
115
<code>NewRoute</code> command. Finally, it returns the identifier of the
116
route it has just created. Once this has happened, the route is
117
completely set up on the server.
121
Finally, the <code>connect</code> function wraps up the necessary calls
122
to routing methods and a use of the <code>NewRoute</code> command to form
123
the client side of the setup.
127
First, let's look at an example of using <code>AMPRouteServerFactory</code> and
128
<code>RoutingAMP</code> to run a server.
131
<a href="listings/amp/route_server.py" class="py-listing">
132
Routed counters server
136
In this example, a simple counting protocol is hooked up to the server.
137
Each route which is created is associated with a new instance of this
138
protocol. The protocol does just one simple thing, it keeps track of how
139
many times the <code>Count</code> command is issued to it and returns
140
this value in the response to that command.
144
Next we'll look at how a client can connect to this server, create new
145
routes, and issue commands over them.
151
Just as servers must, clients must first set up a route before they can
152
send boxes over it. A client uses the same methods as the server,
153
<code>Router.bindRoute</code> and <code>Route.connectTo</code>, to set up
154
a new route. Here's an example which makes one TCP connection to an AMP
155
server, sets up three routes, and then issues multiple commands over each
159
<a href="listings/amp/route_client.py" class="py-listing">
160
Routed counters client
164
Note first how <code>main</code> creates an <code>AMP</code> with a
165
<code>Router</code> instance. Note also how <code>makeRoutes</code>
166
binds and connects the protocol to the default route. This mirrors the
167
route setup which was done on the server and is necessary for the same
172
Once an AMP connection is set up and the default route is bound,
173
<code>makeRoutes</code> uses the previously defined <code>connect</code>
174
function to establish three new routes. Each route is associated with a
175
<code>CountClient</code> instance which will issue several count commands
176
and report the results. The results of each command are tracked so that
177
when they have all been received the client can exit.