Added: 
qpid/site/input/releases/qpid-proton-0.9.1/proton/python/tutorial/tutorial.html
URL: 
http://svn.apache.org/viewvc/qpid/site/input/releases/qpid-proton-0.9.1/proton/python/tutorial/tutorial.html?rev=1681791&view=auto
==============================================================================
--- 
qpid/site/input/releases/qpid-proton-0.9.1/proton/python/tutorial/tutorial.html 
(added)
+++ 
qpid/site/input/releases/qpid-proton-0.9.1/proton/python/tutorial/tutorial.html 
Tue May 26 16:24:06 2015
@@ -0,0 +1,1059 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
+
+
+<html xmlns="http://www.w3.org/1999/xhtml";>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    
+    <title>Tutorial &mdash; Apache Qpid Proton 0.9 documentation</title>
+    
+    <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '',
+        VERSION:     '0.9',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+    <script type="text/javascript" src="_static/jquery.js"></script>
+    <script type="text/javascript" src="_static/underscore.js"></script>
+    <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="top" title="Apache Qpid Proton 0.9 documentation" 
href="index.html" />
+    <link rel="next" title="API Overview" href="overview.html" />
+    <link rel="prev" title="Welcome to Apache Qpid Proton’s documentation!" 
href="index.html" /> 
+  </head>
+  <body>
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        <li class="right" style="margin-right: 10px">
+          <a href="genindex.html" title="General Index"
+             accesskey="I">index</a></li>
+        <li class="right" >
+          <a href="overview.html" title="API Overview"
+             accesskey="N">next</a> |</li>
+        <li class="right" >
+          <a href="index.html" title="Welcome to Apache Qpid Proton’s 
documentation!"
+             accesskey="P">previous</a> |</li>
+        <li><a href="index.html">Apache Qpid Proton 0.9 documentation</a> 
&raquo;</li> 
+      </ul>
+    </div>
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+  <h3><a href="index.html">Table Of Contents</a></h3>
+  <ul>
+<li><a class="reference internal" href="#">Tutorial</a><ul>
+<li><a class="reference internal" href="#hello-world">Hello World!</a></li>
+<li><a class="reference internal" href="#hello-world-direct">Hello World, 
Direct!</a></li>
+<li><a class="reference internal" 
href="#asynchronous-send-and-receive">Asynchronous Send and Receive</a></li>
+<li><a class="reference internal" 
href="#request-response">Request/Response</a><ul>
+<li><a class="reference internal" href="#miscellaneous">Miscellaneous</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+
+  <h4>Previous topic</h4>
+  <p class="topless"><a href="index.html"
+                        title="previous chapter">Welcome to Apache Qpid 
Proton&#8217;s documentation!</a></p>
+  <h4>Next topic</h4>
+  <p class="topless"><a href="overview.html"
+                        title="next chapter">API Overview</a></p>
+  <h3>This Page</h3>
+  <ul class="this-page-menu">
+    <li><a href="_sources/tutorial.txt"
+           rel="nofollow">Show Source</a></li>
+  </ul>
+<div id="searchbox" style="display: none">
+  <h3>Quick search</h3>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" />
+      <input type="submit" value="Go" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    <p class="searchtip" style="font-size: 90%">
+    Enter search terms or a module, class or function name.
+    </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+        </div>
+      </div>
+
+    <div class="document">
+      <div class="documentwrapper">
+        <div class="bodywrapper">
+          <div class="body">
+            
+  <div class="section" id="tutorial">
+<h1>Tutorial<a class="headerlink" href="#tutorial" title="Permalink to this 
headline">¶</a></h1>
+<div class="section" id="hello-world">
+<h2>Hello World!<a class="headerlink" href="#hello-world" title="Permalink to 
this headline">¶</a></h2>
+<p>Tradition dictates that we start with hello world! However rather than
+simply striving for the shortest program possible, we&#8217;ll aim for a
+more illustrative example while still restricting the functionality to
+sending and receiving a single message.</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">from</span> <span class="nn">proton</span> <span 
class="kn">import</span> <span class="n">Message</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+<span class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span>
+
+<span class="k">class</span> <span class="nc">HelloWorld</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">server</span><span class="p">,</span> <span 
class="n">address</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">HelloWorld</span><span class="p">,</span> <span 
class="bp">self</span><span class="p">)</span><span class="o">.</span><span 
class="n">__init__</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">server</span> <span class="o">=</span> <span class="n">server</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">address</span> <span class="o">=</span> <span class="n">address</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="n">conn</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">connect</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span 
class="n">server</span><span class="p">)</span>
+        <span class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_receiver</span><span class="p">(</span><span 
class="n">conn</span><span class="p">,</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">address</span><span class="p">)</span>
+        <span class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_sender</span><span class="p">(</span><span 
class="n">conn</span><span class="p">,</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">address</span><span class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">on_sendable</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="n">event</span><span class="o">.</span><span 
class="n">sender</span><span class="o">.</span><span class="n">send</span><span 
class="p">(</span><span class="n">Message</span><span class="p">(</span><span 
class="n">body</span><span class="o">=</span><span class="s">u&quot;Hello 
World!&quot;</span><span class="p">))</span>
+        <span class="n">event</span><span class="o">.</span><span 
class="n">sender</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+
+    <span class="k">def</span> <span class="nf">on_message</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">print</span> <span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">body</span>
+        <span class="n">event</span><span class="o">.</span><span 
class="n">connection</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+
+<span class="n">Container</span><span class="p">(</span><span 
class="n">HelloWorld</span><span class="p">(</span><span 
class="s">&quot;localhost:5672&quot;</span><span class="p">,</span> <span 
class="s">&quot;examples&quot;</span><span class="p">))</span><span 
class="o">.</span><span class="n">run</span><span class="p">()</span>
+</pre></div>
+</td></tr></table></div>
+<p>You can see the import of <tt class="xref py py-class docutils 
literal"><span class="pre">Container</span></tt> from <tt class="docutils 
literal"><span class="pre">proton.reactor</span></tt> on the
+second line. This is a class that makes programming with proton a
+little easier for the common cases. It includes within it an event
+loop, and programs written using this utility are generally structured
+to react to various events. This reactive style is particularly suited
+to messaging applications.</p>
+<p>To be notified of a particular event, you define a class with the
+appropriately name method on it. That method is then called by the
+event loop when the event occurs.</p>
+<p>We define a class here, <tt class="docutils literal"><span 
class="pre">HelloWorld</span></tt>, which handles the key events of
+interest in sending and receiving a message.</p>
+<p>The <tt class="docutils literal"><span class="pre">on_start()</span></tt> 
method is called when the event loop first
+starts. We handle that by establishing our connection (line 12), a
+sender over which to send the message (line 13) and a receiver over
+which to receive it back again (line 14).</p>
+<p>The <tt class="docutils literal"><span 
class="pre">on_sendable()</span></tt> method is called when message can be 
transferred
+over the associated sender link to the remote peer. We send out our
+<tt class="docutils literal"><span class="pre">Hello</span> <span 
class="pre">World!</span></tt> message (line 17), then close the sender (line 
18) as
+we only want to send one message. The closing of the sender will
+prevent further calls to <tt class="docutils literal"><span 
class="pre">on_sendable()</span></tt>.</p>
+<p>The <tt class="docutils literal"><span class="pre">on_message()</span></tt> 
method is called when a message is
+received. Within that we simply print the body of the message (line
+21) and then close the connection (line 22).</p>
+<p>Now that we have defined the logic for handling these events, we
+create an instance of a <tt class="xref py py-class docutils literal"><span 
class="pre">Container</span></tt>, pass it
+our handler and then enter the event loop by calling
+<tt class="xref py py-meth docutils literal"><span 
class="pre">run()</span></tt>. At this point control
+passes to the container instance, which will make the appropriate
+callbacks to any defined handlers.</p>
+<p>To run the example you will need to have a broker (or similar)
+accepting connections on that url either with a queue (or topic)
+matching the given address or else configured to create such a queue
+(or topic) dynamically. There is a simple broker.py script included
+alongside the examples that can be used for this purpose if
+desired. (It is also written using the API described here, and as such
+gives an example of a slightly more involved application).</p>
+</div>
+<div class="section" id="hello-world-direct">
+<h2>Hello World, Direct!<a class="headerlink" href="#hello-world-direct" 
title="Permalink to this headline">¶</a></h2>
+<p>Though often used in conjunction with a broker, AMQP does not
+<em>require</em> this. It also allows senders and receivers can communicate
+directly if desired.</p>
+<p>Let&#8217;s modify our example to demonstrate this.</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">from</span> <span class="nn">proton</span> <span 
class="kn">import</span> <span class="n">Message</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+<span class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span>
+
+<span class="k">class</span> <span class="nc">HelloWorld</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">url</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">HelloWorld</span><span class="p">,</span> <span 
class="bp">self</span><span class="p">)</span><span class="o">.</span><span 
class="n">__init__</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">url</span> <span class="o">=</span> <span class="n">url</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+<span class="hll">        <span class="bp">self</span><span 
class="o">.</span><span class="n">acceptor</span> <span class="o">=</span> 
<span class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">listen</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">url</span><span 
class="p">)</span>
+</span>        <span class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_sender</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">url</span><span 
class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">on_sendable</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="n">event</span><span class="o">.</span><span 
class="n">sender</span><span class="o">.</span><span class="n">send</span><span 
class="p">(</span><span class="n">Message</span><span class="p">(</span><span 
class="n">body</span><span class="o">=</span><span class="s">u&quot;Hello 
World!&quot;</span><span class="p">))</span>
+        <span class="n">event</span><span class="o">.</span><span 
class="n">sender</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+
+    <span class="k">def</span> <span class="nf">on_message</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">print</span> <span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">body</span>
+
+<span class="hll">    <span class="k">def</span> <span 
class="nf">on_accepted</span><span class="p">(</span><span 
class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+</span><span class="hll">        <span class="n">event</span><span 
class="o">.</span><span class="n">connection</span><span 
class="o">.</span><span class="n">close</span><span class="p">()</span>
+</span>
+<span class="hll">    <span class="k">def</span> <span 
class="nf">on_connection_closed</span><span class="p">(</span><span 
class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+</span><span class="hll">        <span class="bp">self</span><span 
class="o">.</span><span class="n">acceptor</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+</span>
+<span class="n">Container</span><span class="p">(</span><span 
class="n">HelloWorld</span><span class="p">(</span><span 
class="s">&quot;localhost:8888/examples&quot;</span><span 
class="p">))</span><span class="o">.</span><span class="n">run</span><span 
class="p">()</span>
+</pre></div>
+</td></tr></table></div>
+<p>The first difference, on line 11, is that rather than creating a
+receiver on the same connection as our sender, we listen for incoming
+connections by invoking the
+<tt class="xref py py-meth docutils literal"><span 
class="pre">listen()</span></tt> method on the
+container.</p>
+<p>As we only need then to initiate one link, the sender, we can do that
+by passing in a url rather than an existing connection, and the
+connection will also be automatically established for us.</p>
+<p>We send the message in response to the <tt class="docutils literal"><span 
class="pre">on_sendable()</span></tt> callback and
+print the message out in response to the <tt class="docutils literal"><span 
class="pre">on_message()</span></tt> callback
+exactly as before.</p>
+<p>However we also handle two new events. We now close the connection
+from the senders side once the message has been accepted (line
+22). The acceptance of the message is an indication of successful
+transfer to the peer. We are notified of that event through the
+<tt class="docutils literal"><span class="pre">on_accepted()</span></tt> 
callback. Then, once the connection has been closed,
+of which we are notified through the <tt class="docutils literal"><span 
class="pre">on_closed()</span></tt> callback, we stop
+accepting incoming connections (line 25) at which point there is no
+work to be done and the event loop exits, and the run() method will
+return.</p>
+<p>So now we have our example working without a broker involved!</p>
+</div>
+<div class="section" id="asynchronous-send-and-receive">
+<h2>Asynchronous Send and Receive<a class="headerlink" 
href="#asynchronous-send-and-receive" title="Permalink to this 
headline">¶</a></h2>
+<p>Of course, these <tt class="docutils literal"><span 
class="pre">HelloWorld!</span></tt> examples are very artificial,
+communicating as they do over a network connection but with the same
+process. A more realistic example involves communication between
+separate processes (which could indeed be running on completely
+separate machines).</p>
+<p>Let&#8217;s separate the sender from the receiver, and let&#8217;s transfer 
more than
+a single message between them.</p>
+<p>We&#8217;ll start with a simple sender.</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">import</span> <span class="nn">optparse</span>
+<span class="kn">from</span> <span class="nn">proton</span> <span 
class="kn">import</span> <span class="n">Message</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+<span class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span>
+
+<span class="k">class</span> <span class="nc">Send</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">url</span><span class="p">,</span> <span 
class="n">messages</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">Send</span><span class="p">,</span> <span class="bp">self</span><span 
class="p">)</span><span class="o">.</span><span class="n">__init__</span><span 
class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">url</span> <span class="o">=</span> <span class="n">url</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">sent</span> <span class="o">=</span> <span class="mi">0</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">confirmed</span> <span class="o">=</span> <span class="mi">0</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">total</span> <span class="o">=</span> <span class="n">messages</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_sender</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">url</span><span 
class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">on_sendable</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">while</span> <span class="n">event</span><span 
class="o">.</span><span class="n">sender</span><span class="o">.</span><span 
class="n">credit</span> <span class="ow">and</span> <span 
class="bp">self</span><span class="o">.</span><span class="n">sent</span> <span 
class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span 
class="n">total</span><span class="p">:</span>
+            <span class="n">msg</span> <span class="o">=</span> <span 
class="n">Message</span><span class="p">(</span><span class="nb">id</span><span 
class="o">=</span><span class="p">(</span><span class="bp">self</span><span 
class="o">.</span><span class="n">sent</span><span class="o">+</span><span 
class="mi">1</span><span class="p">),</span> <span class="n">body</span><span 
class="o">=</span><span class="p">{</span><span 
class="s">&#39;sequence&#39;</span><span class="p">:(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">sent</span><span 
class="o">+</span><span class="mi">1</span><span class="p">)})</span>
+            <span class="n">event</span><span class="o">.</span><span 
class="n">sender</span><span class="o">.</span><span class="n">send</span><span 
class="p">(</span><span class="n">msg</span><span class="p">)</span>
+            <span class="bp">self</span><span class="o">.</span><span 
class="n">sent</span> <span class="o">+=</span> <span class="mi">1</span>
+
+    <span class="k">def</span> <span class="nf">on_accepted</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">confirmed</span> <span class="o">+=</span> <span class="mi">1</span>
+        <span class="k">if</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">confirmed</span> <span class="o">==</span> 
<span class="bp">self</span><span class="o">.</span><span 
class="n">total</span><span class="p">:</span>
+            <span class="k">print</span> <span class="s">&quot;all messages 
confirmed&quot;</span>
+            <span class="n">event</span><span class="o">.</span><span 
class="n">connection</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+
+    <span class="k">def</span> <span class="nf">on_disconnected</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">sent</span> <span class="o">=</span> <span 
class="bp">self</span><span class="o">.</span><span class="n">confirmed</span>
+
+<span class="n">parser</span> <span class="o">=</span> <span 
class="n">optparse</span><span class="o">.</span><span 
class="n">OptionParser</span><span class="p">(</span><span 
class="n">usage</span><span class="o">=</span><span class="s">&quot;usage: 
%prog [options]&quot;</span><span class="p">,</span>
+                               <span class="n">description</span><span 
class="o">=</span><span class="s">&quot;Send messages to the supplied 
address.&quot;</span><span class="p">)</span>
+<span class="n">parser</span><span class="o">.</span><span 
class="n">add_option</span><span class="p">(</span><span 
class="s">&quot;-a&quot;</span><span class="p">,</span> <span 
class="s">&quot;--address&quot;</span><span class="p">,</span> <span 
class="n">default</span><span class="o">=</span><span 
class="s">&quot;localhost:5672/examples&quot;</span><span class="p">,</span>
+                  <span class="n">help</span><span class="o">=</span><span 
class="s">&quot;address to which messages are sent (default </span><span 
class="si">%d</span><span class="s">efault)&quot;</span><span class="p">)</span>
+<span class="n">parser</span><span class="o">.</span><span 
class="n">add_option</span><span class="p">(</span><span 
class="s">&quot;-m&quot;</span><span class="p">,</span> <span 
class="s">&quot;--messages&quot;</span><span class="p">,</span> <span 
class="nb">type</span><span class="o">=</span><span 
class="s">&quot;int&quot;</span><span class="p">,</span> <span 
class="n">default</span><span class="o">=</span><span 
class="mi">100</span><span class="p">,</span>
+                  <span class="n">help</span><span class="o">=</span><span 
class="s">&quot;number of messages to send (default </span><span 
class="si">%d</span><span class="s">efault)&quot;</span><span class="p">)</span>
+<span class="n">opts</span><span class="p">,</span> <span 
class="n">args</span> <span class="o">=</span> <span 
class="n">parser</span><span class="o">.</span><span 
class="n">parse_args</span><span class="p">()</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">Container</span><span class="p">(</span><span 
class="n">Send</span><span class="p">(</span><span class="n">opts</span><span 
class="o">.</span><span class="n">address</span><span class="p">,</span> <span 
class="n">opts</span><span class="o">.</span><span 
class="n">messages</span><span class="p">))</span><span class="o">.</span><span 
class="n">run</span><span class="p">()</span>
+<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span 
class="p">:</span> <span class="k">pass</span>
+</pre></div>
+</td></tr></table></div>
+<p>As with the previous example, we define the application logic in a
+class that handles various events. As before, we use the
+<tt class="docutils literal"><span class="pre">on_start()</span></tt> event to 
establish our sender link over which we will
+transfer messages and the <tt class="docutils literal"><span 
class="pre">on_sendable()</span></tt> event to know when we can
+transfer our messages.</p>
+<p>Because we are transferring more than one message, we need to keep
+track of how many we have sent. We&#8217;ll use a <tt class="docutils 
literal"><span class="pre">sent</span></tt> member variable
+for that. The <tt class="docutils literal"><span class="pre">total</span></tt> 
member variable will hold the number of
+messages we want to send.</p>
+<p>AMQP defines a credit-based flow control mechanism. Flow control
+allows the receiver to control how many messages it is prepared to
+receive at a given time and thus prevents any component being
+overwhelmed by the number of messages it is sent.</p>
+<p>In the <tt class="docutils literal"><span 
class="pre">on_sendable()</span></tt> callback, we check that our sender has 
credit
+before sending messages. We also check that we haven&#8217;t already sent
+the required number of messages.</p>
+<p>The <tt class="docutils literal"><span class="pre">send()</span></tt> call 
on line 20 is of course asynchronous. When it
+returns the message has not yet actually been transferred across the
+network to the receiver. By handling the <tt class="docutils literal"><span 
class="pre">on_accepted()</span></tt> event, we
+can get notified when the receiver has received and accepted the
+message. In our example we use this event to track the confirmation of
+the messages we have sent. We only close the connection and exit when
+the receiver has received all the messages we wanted to send.</p>
+<p>If we are disconnected after a message is sent and before it has been
+confirmed by the receiver, it is said to be <tt class="docutils literal"><span 
class="pre">in</span> <span class="pre">doubt</span></tt>. We don&#8217;t
+know whether or not it was received. In this example, we will handle
+that by resending any in-doubt messages. This is known as an
+&#8216;at-least-once&#8217; guarantee, since each message should eventually be
+received at least once, though a given message may be received more
+than once (i.e. duplicates are possible). In the <tt class="docutils 
literal"><span class="pre">on_disconnected()</span></tt>
+callback, we reset the sent count to reflect only those that have been
+confirmed. The library will automatically try to reconnect for us, and
+when our sender is sendable again, we can restart from the point we
+know the receiver got to.</p>
+<p>Now let&#8217;s look at the corresponding receiver:</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">import</span> <span class="nn">optparse</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+<span class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span>
+
+<span class="k">class</span> <span class="nc">Recv</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">url</span><span class="p">,</span> <span class="n">count</span><span 
class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">Recv</span><span class="p">,</span> <span class="bp">self</span><span 
class="p">)</span><span class="o">.</span><span class="n">__init__</span><span 
class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">url</span> <span class="o">=</span> <span class="n">url</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">expected</span> <span class="o">=</span> <span class="n">count</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">received</span> <span class="o">=</span> <span class="mi">0</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_receiver</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">url</span><span 
class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">on_message</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">if</span> <span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">id</span> <span class="ow">and</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span class="n">id</span> <span 
class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span 
class="n">received</span><span class="p">:</span>
+            <span class="c"># ignore duplicate message</span>
+            <span class="k">return</span>
+        <span class="k">if</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">expected</span> <span class="o">==</span> 
<span class="mi">0</span> <span class="ow">or</span> <span 
class="bp">self</span><span class="o">.</span><span class="n">received</span> 
<span class="o">&lt;</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">expected</span><span class="p">:</span>
+            <span class="k">print</span> <span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">body</span>
+            <span class="bp">self</span><span class="o">.</span><span 
class="n">received</span> <span class="o">+=</span> <span class="mi">1</span>
+            <span class="k">if</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">received</span> <span class="o">==</span> 
<span class="bp">self</span><span class="o">.</span><span 
class="n">expected</span><span class="p">:</span>
+                <span class="n">event</span><span class="o">.</span><span 
class="n">receiver</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+                <span class="n">event</span><span class="o">.</span><span 
class="n">connection</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+
+<span class="n">parser</span> <span class="o">=</span> <span 
class="n">optparse</span><span class="o">.</span><span 
class="n">OptionParser</span><span class="p">(</span><span 
class="n">usage</span><span class="o">=</span><span class="s">&quot;usage: 
%prog [options]&quot;</span><span class="p">)</span>
+<span class="n">parser</span><span class="o">.</span><span 
class="n">add_option</span><span class="p">(</span><span 
class="s">&quot;-a&quot;</span><span class="p">,</span> <span 
class="s">&quot;--address&quot;</span><span class="p">,</span> <span 
class="n">default</span><span class="o">=</span><span 
class="s">&quot;localhost:5672/examples&quot;</span><span class="p">,</span>
+                  <span class="n">help</span><span class="o">=</span><span 
class="s">&quot;address from which messages are received (default </span><span 
class="si">%d</span><span class="s">efault)&quot;</span><span class="p">)</span>
+<span class="n">parser</span><span class="o">.</span><span 
class="n">add_option</span><span class="p">(</span><span 
class="s">&quot;-m&quot;</span><span class="p">,</span> <span 
class="s">&quot;--messages&quot;</span><span class="p">,</span> <span 
class="nb">type</span><span class="o">=</span><span 
class="s">&quot;int&quot;</span><span class="p">,</span> <span 
class="n">default</span><span class="o">=</span><span 
class="mi">100</span><span class="p">,</span>
+                  <span class="n">help</span><span class="o">=</span><span 
class="s">&quot;number of messages to receive; 0 receives indefinitely (default 
</span><span class="si">%d</span><span class="s">efault)&quot;</span><span 
class="p">)</span>
+<span class="n">opts</span><span class="p">,</span> <span 
class="n">args</span> <span class="o">=</span> <span 
class="n">parser</span><span class="o">.</span><span 
class="n">parse_args</span><span class="p">()</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">Container</span><span class="p">(</span><span 
class="n">Recv</span><span class="p">(</span><span class="n">opts</span><span 
class="o">.</span><span class="n">address</span><span class="p">,</span> <span 
class="n">opts</span><span class="o">.</span><span 
class="n">messages</span><span class="p">))</span><span class="o">.</span><span 
class="n">run</span><span class="p">()</span>
+<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span 
class="p">:</span> <span class="k">pass</span>
+</pre></div>
+</td></tr></table></div>
+<p>Here we handle the <tt class="docutils literal"><span 
class="pre">on_start()</span></tt> by creating our receiver, much like
+we did for the sender. We also handle the <tt class="docutils literal"><span 
class="pre">on_message()</span></tt> event for
+received messages and print the message out as in the <tt class="docutils 
literal"><span class="pre">Hello</span> <span class="pre">World!</span></tt>
+examples. However we add some logic to allow the receiver to wait for
+a given number of messages, then to close the connection and exit. We
+also add some logic to check for and ignore duplicates, using a simple
+sequential id scheme.</p>
+<p>Again, though sending between these two examples requires some sort of
+intermediary process (e.g. a broker), AMQP allows us to send messages
+directly between two processes without this if we so wish. In that
+case one or other of the processes needs to accept incoming socket
+connections. Let&#8217;s create a modified version of the receiving example
+that does this:</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">import</span> <span class="nn">optparse</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+<span class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span>
+
+<span class="k">class</span> <span class="nc">Recv</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">url</span><span class="p">,</span> <span class="n">count</span><span 
class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">Recv</span><span class="p">,</span> <span class="bp">self</span><span 
class="p">)</span><span class="o">.</span><span class="n">__init__</span><span 
class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">url</span> <span class="o">=</span> <span class="n">url</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">expected</span> <span class="o">=</span> <span class="n">count</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">received</span> <span class="o">=</span> <span class="mi">0</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+<span class="hll">        <span class="bp">self</span><span 
class="o">.</span><span class="n">acceptor</span> <span class="o">=</span> 
<span class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">listen</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">url</span><span 
class="p">)</span>
+</span>
+    <span class="k">def</span> <span class="nf">on_message</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">if</span> <span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">id</span> <span class="ow">and</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span class="n">id</span> <span 
class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span 
class="n">received</span><span class="p">:</span>
+            <span class="c"># ignore duplicate message</span>
+            <span class="k">return</span>
+        <span class="k">if</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">expected</span> <span class="o">==</span> 
<span class="mi">0</span> <span class="ow">or</span> <span 
class="bp">self</span><span class="o">.</span><span class="n">received</span> 
<span class="o">&lt;</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">expected</span><span class="p">:</span>
+            <span class="k">print</span> <span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">body</span>
+            <span class="bp">self</span><span class="o">.</span><span 
class="n">received</span> <span class="o">+=</span> <span class="mi">1</span>
+            <span class="k">if</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">received</span> <span class="o">==</span> 
<span class="bp">self</span><span class="o">.</span><span 
class="n">expected</span><span class="p">:</span>
+                <span class="n">event</span><span class="o">.</span><span 
class="n">receiver</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+                <span class="n">event</span><span class="o">.</span><span 
class="n">connection</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+<span class="hll">                <span class="bp">self</span><span 
class="o">.</span><span class="n">acceptor</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+</span>
+<span class="n">parser</span> <span class="o">=</span> <span 
class="n">optparse</span><span class="o">.</span><span 
class="n">OptionParser</span><span class="p">(</span><span 
class="n">usage</span><span class="o">=</span><span class="s">&quot;usage: 
%prog [options]&quot;</span><span class="p">)</span>
+<span class="n">parser</span><span class="o">.</span><span 
class="n">add_option</span><span class="p">(</span><span 
class="s">&quot;-a&quot;</span><span class="p">,</span> <span 
class="s">&quot;--address&quot;</span><span class="p">,</span> <span 
class="n">default</span><span class="o">=</span><span 
class="s">&quot;localhost:5672/examples&quot;</span><span class="p">,</span>
+                  <span class="n">help</span><span class="o">=</span><span 
class="s">&quot;address from which messages are received (default </span><span 
class="si">%d</span><span class="s">efault)&quot;</span><span class="p">)</span>
+<span class="n">parser</span><span class="o">.</span><span 
class="n">add_option</span><span class="p">(</span><span 
class="s">&quot;-m&quot;</span><span class="p">,</span> <span 
class="s">&quot;--messages&quot;</span><span class="p">,</span> <span 
class="nb">type</span><span class="o">=</span><span 
class="s">&quot;int&quot;</span><span class="p">,</span> <span 
class="n">default</span><span class="o">=</span><span 
class="mi">100</span><span class="p">,</span>
+                  <span class="n">help</span><span class="o">=</span><span 
class="s">&quot;number of messages to receive; 0 receives indefinitely (default 
</span><span class="si">%d</span><span class="s">efault)&quot;</span><span 
class="p">)</span>
+<span class="n">opts</span><span class="p">,</span> <span 
class="n">args</span> <span class="o">=</span> <span 
class="n">parser</span><span class="o">.</span><span 
class="n">parse_args</span><span class="p">()</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">Container</span><span class="p">(</span><span 
class="n">Recv</span><span class="p">(</span><span class="n">opts</span><span 
class="o">.</span><span class="n">address</span><span class="p">,</span> <span 
class="n">opts</span><span class="o">.</span><span 
class="n">messages</span><span class="p">))</span><span class="o">.</span><span 
class="n">run</span><span class="p">()</span>
+<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span 
class="p">:</span> <span class="k">pass</span>
+</pre></div>
+</td></tr></table></div>
+<p>There are only two differences here. On line 13, instead of initiating
+a link (and implicitly a connection), we listen for incoming
+connections. On line 25, when we have received all the expected
+messages, we then stop listening for incoming connections by closing
+the acceptor object.</p>
+<p>You can use the original send example now to send to this receiver
+directly. (Note: you will need to stop any broker that is listening on
+the 5672 port, or else change the port used by specifying a different
+address to each example via the -a command line switch).</p>
+<p>We could equally well modify the original sender to allow the original
+receiver to connect to it. Again that just requires two modifications:</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">import</span> <span class="nn">optparse</span>
+<span class="kn">from</span> <span class="nn">proton</span> <span 
class="kn">import</span> <span class="n">Message</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+<span class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span>
+
+<span class="k">class</span> <span class="nc">Send</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">url</span><span class="p">,</span> <span 
class="n">messages</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">Send</span><span class="p">,</span> <span class="bp">self</span><span 
class="p">)</span><span class="o">.</span><span class="n">__init__</span><span 
class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">url</span> <span class="o">=</span> <span class="n">url</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">sent</span> <span class="o">=</span> <span class="mi">0</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">confirmed</span> <span class="o">=</span> <span class="mi">0</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">total</span> <span class="o">=</span> <span class="n">messages</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+<span class="hll">        <span class="bp">self</span><span 
class="o">.</span><span class="n">acceptor</span> <span class="o">=</span> 
<span class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">listen</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">url</span><span 
class="p">)</span>
+</span>
+    <span class="k">def</span> <span class="nf">on_sendable</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">while</span> <span class="n">event</span><span 
class="o">.</span><span class="n">sender</span><span class="o">.</span><span 
class="n">credit</span> <span class="ow">and</span> <span 
class="bp">self</span><span class="o">.</span><span class="n">sent</span> <span 
class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span 
class="n">total</span><span class="p">:</span>
+            <span class="n">msg</span> <span class="o">=</span> <span 
class="n">Message</span><span class="p">(</span><span class="nb">id</span><span 
class="o">=</span><span class="p">(</span><span class="bp">self</span><span 
class="o">.</span><span class="n">sent</span><span class="o">+</span><span 
class="mi">1</span><span class="p">),</span> <span class="n">body</span><span 
class="o">=</span><span class="p">{</span><span 
class="s">&#39;sequence&#39;</span><span class="p">:(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">sent</span><span 
class="o">+</span><span class="mi">1</span><span class="p">)})</span>
+            <span class="n">event</span><span class="o">.</span><span 
class="n">sender</span><span class="o">.</span><span class="n">send</span><span 
class="p">(</span><span class="n">msg</span><span class="p">)</span>
+            <span class="bp">self</span><span class="o">.</span><span 
class="n">sent</span> <span class="o">+=</span> <span class="mi">1</span>
+
+    <span class="k">def</span> <span class="nf">on_accepted</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">confirmed</span> <span class="o">+=</span> <span class="mi">1</span>
+        <span class="k">if</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">confirmed</span> <span class="o">==</span> 
<span class="bp">self</span><span class="o">.</span><span 
class="n">total</span><span class="p">:</span>
+            <span class="k">print</span> <span class="s">&quot;all messages 
confirmed&quot;</span>
+            <span class="n">event</span><span class="o">.</span><span 
class="n">connection</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+<span class="hll">            <span class="bp">self</span><span 
class="o">.</span><span class="n">acceptor</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+</span>
+    <span class="k">def</span> <span class="nf">on_disconnected</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">sent</span> <span class="o">=</span> <span 
class="bp">self</span><span class="o">.</span><span class="n">confirmed</span>
+
+<span class="n">parser</span> <span class="o">=</span> <span 
class="n">optparse</span><span class="o">.</span><span 
class="n">OptionParser</span><span class="p">(</span><span 
class="n">usage</span><span class="o">=</span><span class="s">&quot;usage: 
%prog [options]&quot;</span><span class="p">,</span>
+                               <span class="n">description</span><span 
class="o">=</span><span class="s">&quot;Send messages to the supplied 
address.&quot;</span><span class="p">)</span>
+<span class="n">parser</span><span class="o">.</span><span 
class="n">add_option</span><span class="p">(</span><span 
class="s">&quot;-a&quot;</span><span class="p">,</span> <span 
class="s">&quot;--address&quot;</span><span class="p">,</span> <span 
class="n">default</span><span class="o">=</span><span 
class="s">&quot;localhost:5672/examples&quot;</span><span class="p">,</span>
+                  <span class="n">help</span><span class="o">=</span><span 
class="s">&quot;address to which messages are sent (default </span><span 
class="si">%d</span><span class="s">efault)&quot;</span><span class="p">)</span>
+<span class="n">parser</span><span class="o">.</span><span 
class="n">add_option</span><span class="p">(</span><span 
class="s">&quot;-m&quot;</span><span class="p">,</span> <span 
class="s">&quot;--messages&quot;</span><span class="p">,</span> <span 
class="nb">type</span><span class="o">=</span><span 
class="s">&quot;int&quot;</span><span class="p">,</span> <span 
class="n">default</span><span class="o">=</span><span 
class="mi">100</span><span class="p">,</span>
+                  <span class="n">help</span><span class="o">=</span><span 
class="s">&quot;number of messages to send (default </span><span 
class="si">%d</span><span class="s">efault)&quot;</span><span class="p">)</span>
+<span class="n">opts</span><span class="p">,</span> <span 
class="n">args</span> <span class="o">=</span> <span 
class="n">parser</span><span class="o">.</span><span 
class="n">parse_args</span><span class="p">()</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">Container</span><span class="p">(</span><span 
class="n">Send</span><span class="p">(</span><span class="n">opts</span><span 
class="o">.</span><span class="n">address</span><span class="p">,</span> <span 
class="n">opts</span><span class="o">.</span><span 
class="n">messages</span><span class="p">))</span><span class="o">.</span><span 
class="n">run</span><span class="p">()</span>
+<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span 
class="p">:</span> <span class="k">pass</span>
+</pre></div>
+</td></tr></table></div>
+<p>As with the modified receiver, instead of initiating establishment of
+a link, we listen for incoming connections on line 15 and then on line
+28, when we have received confirmation of all the messages we sent, we
+can close the acceptor in order to exit. The symmetry in the
+underlying AMQP that enables this is quite unique and elegant, and in
+reflecting this the proton API provides a flexible toolkit for
+implementing all sorts of interesting intermediaries (the broker.py
+script provided as a simple broker for testing purposes provides an
+example of this).</p>
+<p>To try this modified sender, run the original receiver against it.</p>
+</div>
+<div class="section" id="request-response">
+<h2>Request/Response<a class="headerlink" href="#request-response" 
title="Permalink to this headline">¶</a></h2>
+<p>A common pattern is to send a request message and expect a response
+message in return. AMQP has special support for this pattern. Let&#8217;s
+have a look at a simple example. We&#8217;ll start with the 
&#8216;server&#8217;,
+i.e. the program that will process the request and send the
+response. Note that we are still using a broker in this example.</p>
+<p>Our server will provide a very simple service: it will respond with
+the body of the request converted to uppercase.</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">from</span> <span class="nn">proton</span> <span 
class="kn">import</span> <span class="n">Message</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+<span class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span>
+
+<span class="k">class</span> <span class="nc">Server</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">url</span><span class="p">,</span> <span 
class="n">address</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">Server</span><span class="p">,</span> <span 
class="bp">self</span><span class="p">)</span><span class="o">.</span><span 
class="n">__init__</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">url</span> <span class="o">=</span> <span class="n">url</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">address</span> <span class="o">=</span> <span class="n">address</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">senders</span> <span class="o">=</span> <span class="p">{}</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">print</span> <span class="s">&quot;Listening 
on&quot;</span><span class="p">,</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">url</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">container</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span class="n">container</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">conn</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">connect</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">url</span><span 
class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">receiver</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_receiver</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">conn</span><span 
class="p">,</span> <span class="bp">self</span><span class="o">.</span><span 
class="n">address</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">relay</span> <span class="o">=</span> <span class="bp">None</span>
+
+    <span class="k">def</span> <span 
class="nf">on_connection_opened</span><span class="p">(</span><span 
class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">if</span> <span class="n">event</span><span 
class="o">.</span><span class="n">connection</span><span 
class="o">.</span><span class="n">remote_offered_capabilities</span> <span 
class="ow">and</span> <span class="s">&#39;ANONYMOUS-RELAY&#39;</span> <span 
class="ow">in</span> <span class="n">event</span><span class="o">.</span><span 
class="n">connection</span><span class="o">.</span><span 
class="n">remote_offered_capabilities</span><span class="p">:</span>
+            <span class="bp">self</span><span class="o">.</span><span 
class="n">relay</span> <span class="o">=</span> <span 
class="bp">self</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_sender</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">conn</span><span 
class="p">,</span> <span class="bp">None</span><span class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">on_message</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">print</span> <span 
class="s">&quot;Received&quot;</span><span class="p">,</span> <span 
class="n">event</span><span class="o">.</span><span class="n">message</span>
+        <span class="n">sender</span> <span class="o">=</span> <span 
class="bp">self</span><span class="o">.</span><span class="n">relay</span> 
<span class="ow">or</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">senders</span><span class="o">.</span><span 
class="n">get</span><span class="p">(</span><span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">reply_to</span><span class="p">)</span>
+        <span class="k">if</span> <span class="ow">not</span> <span 
class="n">sender</span><span class="p">:</span>
+            <span class="n">sender</span> <span class="o">=</span> <span 
class="bp">self</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_sender</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">conn</span><span 
class="p">,</span> <span class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span 
class="n">reply_to</span><span class="p">)</span>
+            <span class="bp">self</span><span class="o">.</span><span 
class="n">senders</span><span class="p">[</span><span 
class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span 
class="n">reply_to</span><span class="p">]</span> <span class="o">=</span> 
<span class="n">sender</span>
+        <span class="n">sender</span><span class="o">.</span><span 
class="n">send</span><span class="p">(</span><span 
class="n">Message</span><span class="p">(</span><span 
class="n">address</span><span class="o">=</span><span 
class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span 
class="n">reply_to</span><span class="p">,</span> <span 
class="n">body</span><span class="o">=</span><span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">body</span><span class="o">.</span><span class="n">upper</span><span 
class="p">(),</span>
+                            <span class="n">correlation_id</span><span 
class="o">=</span><span class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span 
class="n">correlation_id</span><span class="p">))</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">Container</span><span class="p">(</span><span 
class="n">Server</span><span class="p">(</span><span 
class="s">&quot;0.0.0.0:5672&quot;</span><span class="p">,</span> <span 
class="s">&quot;examples&quot;</span><span class="p">))</span><span 
class="o">.</span><span class="n">run</span><span class="p">()</span>
+<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span 
class="p">:</span> <span class="k">pass</span>
+</pre></div>
+</td></tr></table></div>
+<p>The code here is not too different from the simple receiver
+example. When we receive a request however, we look at the
+<tt class="xref py py-attr docutils literal"><span 
class="pre">reply_to</span></tt> address on the
+<tt class="xref py py-class docutils literal"><span 
class="pre">Message</span></tt> and create a sender for that over which to
+send the response. We&#8217;ll cache the senders incase we get further
+requests with the same reply_to.</p>
+<p>Now let&#8217;s create a simple client to test this service out.</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">import</span> <span class="nn">optparse</span>
+<span class="kn">from</span> <span class="nn">proton</span> <span 
class="kn">import</span> <span class="n">Message</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+<span class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span><span 
class="p">,</span> <span class="n">DynamicNodeProperties</span>
+
+<span class="k">class</span> <span class="nc">Client</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">url</span><span class="p">,</span> <span 
class="n">requests</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">Client</span><span class="p">,</span> <span 
class="bp">self</span><span class="p">)</span><span class="o">.</span><span 
class="n">__init__</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">url</span> <span class="o">=</span> <span class="n">url</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">requests</span> <span class="o">=</span> <span 
class="n">requests</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">sender</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_sender</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">url</span><span 
class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">receiver</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">create_receiver</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span 
class="n">sender</span><span class="o">.</span><span 
class="n">connection</span><span class="p">,</span> <span 
class="bp">None</span><span class="p">,</span> <span 
class="n">dynamic</span><span class="o">=</span><span 
class="bp">True</span><span class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">next_request</span><span 
class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="k">if</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">receiver</span><span class="o">.</span><span 
class="n">remote_source</span><span class="o">.</span><span 
class="n">address</span><span class="p">:</span>
+            <span class="n">req</span> <span class="o">=</span> <span 
class="n">Message</span><span class="p">(</span><span 
class="n">reply_to</span><span class="o">=</span><span 
class="bp">self</span><span class="o">.</span><span 
class="n">receiver</span><span class="o">.</span><span 
class="n">remote_source</span><span class="o">.</span><span 
class="n">address</span><span class="p">,</span> <span 
class="n">body</span><span class="o">=</span><span class="bp">self</span><span 
class="o">.</span><span class="n">requests</span><span class="p">[</span><span 
class="mi">0</span><span class="p">])</span>
+            <span class="bp">self</span><span class="o">.</span><span 
class="n">sender</span><span class="o">.</span><span class="n">send</span><span 
class="p">(</span><span class="n">req</span><span class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">on_link_opened</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">if</span> <span class="n">event</span><span 
class="o">.</span><span class="n">receiver</span> <span class="o">==</span> 
<span class="bp">self</span><span class="o">.</span><span 
class="n">receiver</span><span class="p">:</span>
+            <span class="bp">self</span><span class="o">.</span><span 
class="n">next_request</span><span class="p">()</span>
+
+    <span class="k">def</span> <span class="nf">on_message</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">print</span> <span class="s">&quot;</span><span 
class="si">%s</span><span class="s"> =&gt; </span><span 
class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> 
<span class="p">(</span><span class="bp">self</span><span 
class="o">.</span><span class="n">requests</span><span class="o">.</span><span 
class="n">pop</span><span class="p">(</span><span class="mi">0</span><span 
class="p">),</span> <span class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span 
class="n">body</span><span class="p">)</span>
+        <span class="k">if</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">requests</span><span class="p">:</span>
+            <span class="bp">self</span><span class="o">.</span><span 
class="n">next_request</span><span class="p">()</span>
+        <span class="k">else</span><span class="p">:</span>
+            <span class="n">event</span><span class="o">.</span><span 
class="n">connection</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+
+<span class="n">REQUESTS</span><span class="o">=</span> <span 
class="p">[</span><span class="s">&quot;Twas brillig, and the slithy 
toves&quot;</span><span class="p">,</span>
+           <span class="s">&quot;Did gire and gymble in the 
wabe.&quot;</span><span class="p">,</span>
+           <span class="s">&quot;All mimsy were the 
borogroves,&quot;</span><span class="p">,</span>
+           <span class="s">&quot;And the mome raths 
outgrabe.&quot;</span><span class="p">]</span>
+
+<span class="n">parser</span> <span class="o">=</span> <span 
class="n">optparse</span><span class="o">.</span><span 
class="n">OptionParser</span><span class="p">(</span><span 
class="n">usage</span><span class="o">=</span><span class="s">&quot;usage: 
%prog [options]&quot;</span><span class="p">,</span>
+                               <span class="n">description</span><span 
class="o">=</span><span class="s">&quot;Send requests to the supplied address 
and print responses.&quot;</span><span class="p">)</span>
+<span class="n">parser</span><span class="o">.</span><span 
class="n">add_option</span><span class="p">(</span><span 
class="s">&quot;-a&quot;</span><span class="p">,</span> <span 
class="s">&quot;--address&quot;</span><span class="p">,</span> <span 
class="n">default</span><span class="o">=</span><span 
class="s">&quot;localhost:5672/examples&quot;</span><span class="p">,</span>
+                  <span class="n">help</span><span class="o">=</span><span 
class="s">&quot;address to which messages are sent (default </span><span 
class="si">%d</span><span class="s">efault)&quot;</span><span class="p">)</span>
+<span class="n">opts</span><span class="p">,</span> <span 
class="n">args</span> <span class="o">=</span> <span 
class="n">parser</span><span class="o">.</span><span 
class="n">parse_args</span><span class="p">()</span>
+
+<span class="n">Container</span><span class="p">(</span><span 
class="n">Client</span><span class="p">(</span><span class="n">opts</span><span 
class="o">.</span><span class="n">address</span><span class="p">,</span> <span 
class="n">args</span> <span class="ow">or</span> <span 
class="n">REQUESTS</span><span class="p">))</span><span class="o">.</span><span 
class="n">run</span><span class="p">()</span>
+</pre></div>
+</td></tr></table></div>
+<p>As well as sending requests, we need to be able to get back the
+responses. We create a receiver for that (see line 14), but we don&#8217;t
+specify an address, we set the dynamic option which tells the broker
+we are connected to to create a temporary address over which we can
+receive our responses.</p>
+<p>We need to use the address allocated by the broker as the reply_to
+address of our requests, so we can&#8217;t send them until the broker has
+confirmed our receiving link has been set up (at which point we will
+have our allocated address). To do that, we add an
+<tt class="docutils literal"><span class="pre">on_link_opened()</span></tt> 
method to our handler class, and if the link
+associated with event is the receiver, we use that as the trigger to
+send our first request.</p>
+<p>Again, we could avoid having any intermediary process here if we
+wished. The following code implementas a server to which the client
+above could connect directly without any need for a broker or similar.</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">from</span> <span class="nn">proton</span> <span 
class="kn">import</span> <span class="n">generate_uuid</span><span 
class="p">,</span> <span class="n">Message</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+<span class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span>
+
+<span class="k">class</span> <span class="nc">Server</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">url</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">Server</span><span class="p">,</span> <span 
class="bp">self</span><span class="p">)</span><span class="o">.</span><span 
class="n">__init__</span><span class="p">()</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">url</span> <span class="o">=</span> <span class="n">url</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">senders</span> <span class="o">=</span> <span class="p">{}</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">print</span> <span class="s">&quot;Listening 
on&quot;</span><span class="p">,</span> <span class="bp">self</span><span 
class="o">.</span><span class="n">url</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">container</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span class="n">container</span>
+        <span class="bp">self</span><span class="o">.</span><span 
class="n">acceptor</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">listen</span><span class="p">(</span><span 
class="bp">self</span><span class="o">.</span><span class="n">url</span><span 
class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">on_link_opening</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">if</span> <span class="n">event</span><span 
class="o">.</span><span class="n">link</span><span class="o">.</span><span 
class="n">is_sender</span><span class="p">:</span>
+            <span class="k">if</span> <span class="n">event</span><span 
class="o">.</span><span class="n">link</span><span class="o">.</span><span 
class="n">remote_source</span> <span class="ow">and</span> <span 
class="n">event</span><span class="o">.</span><span class="n">link</span><span 
class="o">.</span><span class="n">remote_source</span><span 
class="o">.</span><span class="n">dynamic</span><span class="p">:</span>
+                <span class="n">event</span><span class="o">.</span><span 
class="n">link</span><span class="o">.</span><span class="n">source</span><span 
class="o">.</span><span class="n">address</span> <span class="o">=</span> <span 
class="nb">str</span><span class="p">(</span><span 
class="n">generate_uuid</span><span class="p">())</span>
+                <span class="bp">self</span><span class="o">.</span><span 
class="n">senders</span><span class="p">[</span><span 
class="n">event</span><span class="o">.</span><span class="n">link</span><span 
class="o">.</span><span class="n">source</span><span class="o">.</span><span 
class="n">address</span><span class="p">]</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span class="n">link</span>
+            <span class="k">elif</span> <span class="n">event</span><span 
class="o">.</span><span class="n">link</span><span class="o">.</span><span 
class="n">remote_target</span> <span class="ow">and</span> <span 
class="n">event</span><span class="o">.</span><span class="n">link</span><span 
class="o">.</span><span class="n">remote_target</span><span 
class="o">.</span><span class="n">address</span><span class="p">:</span>
+                <span class="n">event</span><span class="o">.</span><span 
class="n">link</span><span class="o">.</span><span class="n">target</span><span 
class="o">.</span><span class="n">address</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span class="n">link</span><span 
class="o">.</span><span class="n">remote_target</span><span 
class="o">.</span><span class="n">address</span>
+                <span class="bp">self</span><span class="o">.</span><span 
class="n">senders</span><span class="p">[</span><span 
class="n">event</span><span class="o">.</span><span class="n">link</span><span 
class="o">.</span><span class="n">remote_target</span><span 
class="o">.</span><span class="n">address</span><span class="p">]</span> <span 
class="o">=</span> <span class="n">event</span><span class="o">.</span><span 
class="n">link</span>
+            <span class="k">elif</span> <span class="n">event</span><span 
class="o">.</span><span class="n">link</span><span class="o">.</span><span 
class="n">remote_source</span><span class="p">:</span>
+                <span class="n">event</span><span class="o">.</span><span 
class="n">link</span><span class="o">.</span><span class="n">source</span><span 
class="o">.</span><span class="n">address</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span class="n">link</span><span 
class="o">.</span><span class="n">remote_source</span><span 
class="o">.</span><span class="n">address</span>
+        <span class="k">elif</span> <span class="n">event</span><span 
class="o">.</span><span class="n">link</span><span class="o">.</span><span 
class="n">remote_target</span><span class="p">:</span>
+            <span class="n">event</span><span class="o">.</span><span 
class="n">link</span><span class="o">.</span><span class="n">target</span><span 
class="o">.</span><span class="n">address</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span class="n">link</span><span 
class="o">.</span><span class="n">remote_target</span><span 
class="o">.</span><span class="n">address</span>
+
+    <span class="k">def</span> <span class="nf">on_message</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">print</span> <span 
class="s">&quot;Received&quot;</span><span class="p">,</span> <span 
class="n">event</span><span class="o">.</span><span class="n">message</span>
+        <span class="n">sender</span> <span class="o">=</span> <span 
class="bp">self</span><span class="o">.</span><span 
class="n">senders</span><span class="o">.</span><span class="n">get</span><span 
class="p">(</span><span class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span 
class="n">reply_to</span><span class="p">)</span>
+        <span class="k">if</span> <span class="ow">not</span> <span 
class="n">sender</span><span class="p">:</span>
+            <span class="k">print</span> <span class="s">&quot;No link for 
reply&quot;</span>
+            <span class="k">return</span>
+        <span class="n">sender</span><span class="o">.</span><span 
class="n">send</span><span class="p">(</span><span 
class="n">Message</span><span class="p">(</span><span 
class="n">address</span><span class="o">=</span><span 
class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span 
class="n">reply_to</span><span class="p">,</span> <span 
class="n">body</span><span class="o">=</span><span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">body</span><span class="o">.</span><span class="n">upper</span><span 
class="p">(),</span>
+                            <span class="n">correlation_id</span><span 
class="o">=</span><span class="n">event</span><span class="o">.</span><span 
class="n">message</span><span class="o">.</span><span 
class="n">correlation_id</span><span class="p">))</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">Container</span><span class="p">(</span><span 
class="n">Server</span><span class="p">(</span><span 
class="s">&quot;0.0.0.0:8888&quot;</span><span class="p">))</span><span 
class="o">.</span><span class="n">run</span><span class="p">()</span>
+<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span 
class="p">:</span> <span class="k">pass</span>
+</pre></div>
+</td></tr></table></div>
+<p>Though this requires some more extensive changes than the simple
+sending and receiving examples, the essence of the program is still
+the same. Here though, rather than the server establishing a link for
+the response, it relies on the link that the client established, since
+that now comes in directly to the server process.</p>
+<div class="section" id="miscellaneous">
+<h3>Miscellaneous<a class="headerlink" href="#miscellaneous" title="Permalink 
to this headline">¶</a></h3>
+<p>Many brokers offer the ability to consume messages based on a
+&#8216;selector&#8217; that defines which messages are of interest based on
+particular values of the headers. The following example shows how that
+can be achieved:</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span><span 
class="p">,</span> <span class="n">Selector</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+
+<span class="k">class</span> <span class="nc">Recv</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">Recv</span><span class="p">,</span> <span class="bp">self</span><span 
class="p">)</span><span class="o">.</span><span class="n">__init__</span><span 
class="p">()</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="n">conn</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">connect</span><span class="p">(</span><span 
class="s">&quot;localhost:5672&quot;</span><span class="p">)</span>
+<span class="hll">        <span class="n">event</span><span 
class="o">.</span><span class="n">container</span><span class="o">.</span><span 
class="n">create_receiver</span><span class="p">(</span><span 
class="n">conn</span><span class="p">,</span> <span 
class="s">&quot;examples&quot;</span><span class="p">,</span> <span 
class="n">options</span><span class="o">=</span><span 
class="n">Selector</span><span class="p">(</span><span class="s">u&quot;colour 
= &#39;green&#39;&quot;</span><span class="p">))</span>
+</span>
+    <span class="k">def</span> <span class="nf">on_message</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">print</span> <span class="n">event</span><span 
class="o">.</span><span class="n">message</span><span class="o">.</span><span 
class="n">body</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">Container</span><span class="p">(</span><span 
class="n">Recv</span><span class="p">())</span><span class="o">.</span><span 
class="n">run</span><span class="p">()</span>
+<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span 
class="p">:</span> <span class="k">pass</span>
+</pre></div>
+</td></tr></table></div>
+<p>When creating the receiver, we specify a Selector object as an
+option. The options argument can take a single object or a
+list. Another option that is sometimes of interest when using a broker
+is the ability to &#8216;browse&#8217; the messages on a queue, rather than
+consumig them. This is done in AMQP by specifying a distribution mode
+of &#8216;copy&#8217; (instead of &#8216;move&#8217; which is the expected 
default for
+queues). An example of that is shown next:</p>
+<div class="highlight-python"><table class="highlighttable"><tr><td 
class="linenos"><div class="linenodiv"><pre> 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19</pre></div></td><td class="code"><div class="highlight"><pre><span 
class="kn">from</span> <span class="nn">proton.reactor</span> <span 
class="kn">import</span> <span class="n">Container</span><span 
class="p">,</span> <span class="n">Copy</span>
+<span class="kn">from</span> <span class="nn">proton.handlers</span> <span 
class="kn">import</span> <span class="n">MessagingHandler</span>
+
+<span class="k">class</span> <span class="nc">Recv</span><span 
class="p">(</span><span class="n">MessagingHandler</span><span 
class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span 
class="p">(</span><span class="bp">self</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span 
class="n">Recv</span><span class="p">,</span> <span class="bp">self</span><span 
class="p">)</span><span class="o">.</span><span class="n">__init__</span><span 
class="p">()</span>
+
+    <span class="k">def</span> <span class="nf">on_start</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="n">conn</span> <span class="o">=</span> <span 
class="n">event</span><span class="o">.</span><span 
class="n">container</span><span class="o">.</span><span 
class="n">connect</span><span class="p">(</span><span 
class="s">&quot;localhost:5672&quot;</span><span class="p">)</span>
+<span class="hll">        <span class="n">event</span><span 
class="o">.</span><span class="n">container</span><span class="o">.</span><span 
class="n">create_receiver</span><span class="p">(</span><span 
class="n">conn</span><span class="p">,</span> <span 
class="s">&quot;examples&quot;</span><span class="p">,</span> <span 
class="n">options</span><span class="o">=</span><span 
class="n">Copy</span><span class="p">())</span>
+</span>
+    <span class="k">def</span> <span class="nf">on_message</span><span 
class="p">(</span><span class="bp">self</span><span class="p">,</span> <span 
class="n">event</span><span class="p">):</span>
+        <span class="k">print</span> <span class="n">event</span><span 
class="o">.</span><span class="n">message</span>
+        <span class="k">if</span> <span class="n">event</span><span 
class="o">.</span><span class="n">receiver</span><span class="o">.</span><span 
class="n">queued</span> <span class="o">==</span> <span class="mi">0</span> 
<span class="ow">and</span> <span class="n">event</span><span 
class="o">.</span><span class="n">receiver</span><span class="o">.</span><span 
class="n">drained</span><span class="p">:</span>
+            <span class="n">event</span><span class="o">.</span><span 
class="n">connection</span><span class="o">.</span><span 
class="n">close</span><span class="p">()</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">Container</span><span class="p">(</span><span 
class="n">Recv</span><span class="p">())</span><span class="o">.</span><span 
class="n">run</span><span class="p">()</span>
+<span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span 
class="p">:</span> <span class="k">pass</span>
+</pre></div>
+</td></tr></table></div>
+</div>
+</div>
+</div>
+
+
+          </div>
+        </div>
+      </div>

[... 25 lines stripped ...]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to