You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by mc...@apache.org on 2015/06/04 15:52:22 UTC

[1/4] qpid-proton git commit: PROTON-897: Renamed passive_recv.rb to nonblocking_recv.rb

Repository: qpid-proton
Updated Branches:
  refs/heads/master 89ef63b46 -> caaabb7bd


PROTON-897: Renamed passive_recv.rb to nonblocking_recv.rb

The name is a little more specific as to what the example shows.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/267072da
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/267072da
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/267072da

Branch: refs/heads/master
Commit: 267072da7de4d24cad7f9838b917160b3135bd13
Parents: ac4731f
Author: Darryl L. Pierce <mc...@gmail.com>
Authored: Mon Jun 1 11:36:15 2015 -0400
Committer: Darryl L. Pierce <mc...@gmail.com>
Committed: Thu Jun 4 08:28:46 2015 -0400

----------------------------------------------------------------------
 examples/ruby/messenger/nonblocking_recv.rb | 140 +++++++++++++++++++++++
 examples/ruby/messenger/passive_recv.rb     | 140 -----------------------
 2 files changed, 140 insertions(+), 140 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/267072da/examples/ruby/messenger/nonblocking_recv.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/messenger/nonblocking_recv.rb b/examples/ruby/messenger/nonblocking_recv.rb
new file mode 100644
index 0000000..d1fa854
--- /dev/null
+++ b/examples/ruby/messenger/nonblocking_recv.rb
@@ -0,0 +1,140 @@
+#!/usr/bin/env ruby
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+require 'qpid_proton'
+require 'optparse'
+
+addresses = []
+
+OptionParser.new do |opts|
+  opts.banner = "Usage: recv.rb <addr1> ... <addrn>"
+  opts.parse!
+
+  addresses = ARGV
+end
+
+addresses = ["~0.0.0.0"] if addresses.empty?
+
+messenger = Qpid::Proton::Messenger::Messenger.new
+messenger.passive = true
+
+begin
+  messenger.start
+rescue ProtonError => error
+  puts "ERROR: #{error.message}"
+  puts error.backtrace.join("\n")
+  exit
+end
+
+addresses.each do |address|
+  begin
+    messenger.subscribe(address)
+  rescue Qpid::Proton::ProtonError => error
+    puts "ERROR: #{error.message}"
+    exit
+  end
+end
+
+msg = Qpid::Proton::Message.new
+
+read_array = []
+write_array = []
+selectables = {}
+
+loop do
+
+  # wait for incoming messages
+  sel = messenger.selectable
+  while !sel.nil?
+    if sel.terminal?
+      selectables.delete(sel.fileno)
+      read_array.delete(sel)
+      write_array.delete(sel)
+      sel.free
+    else
+      sel.capacity
+      sel.pending
+      if !sel.registered?
+        read_array << sel
+        write_array << sel
+        selectables[sel.fileno] = sel
+        sel.registered = true
+      end
+    end
+    sel = messenger.selectable
+  end
+
+  unless selectables.empty?
+    rarray = []; read_array.each {|fd| rarray << fd.to_io }
+    warray = []; write_array.each {|fd| warray << fd.to_io }
+
+    if messenger.deadline > 0.0
+      result = IO.select(rarray, warray, nil, messenger.deadline)
+    else
+      result = IO.select(rarray, warray)
+    end
+
+    unless result.nil? && result.empty?
+      result.flatten.each do |io|
+        sel = selectables[io.fileno]
+
+        sel.writable if sel.pending > 0
+        sel.readable if sel.capacity > 0
+      end
+    end
+
+    begin
+      messenger.receive(10)
+    rescue Qpid::Proton::ProtonError => error
+      puts "ERROR: #{error.message}"
+      exit
+    end
+
+    while messenger.incoming.nonzero?
+      begin
+        messenger.get(msg)
+      rescue Qpid::Proton::Error => error
+        puts "ERROR: #{error.message}"
+        exit
+      end
+
+      puts "Address: #{msg.address}"
+      subject = msg.subject || "(no subject)"
+      puts "Subject: #{subject}"
+      puts "Body: #{msg.body}"
+      puts "Properties: #{msg.properties}"
+      puts "Instructions: #{msg.instructions}"
+      puts "Annotations: #{msg.annotations}"
+
+      if msg.reply_to
+        puts "=== Sending a reply to #{msg.reply_to}"
+        reply = Qpid::Proton::Message.new
+        reply.address = msg.reply_to
+        reply.subject = "RE: #{msg.subject}"
+        reply.content = "Thanks for the message!"
+
+        messenger.put(reply)
+        messenger.send
+      end
+    end
+  end
+end
+
+messenger.stop
+

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/267072da/examples/ruby/messenger/passive_recv.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/messenger/passive_recv.rb b/examples/ruby/messenger/passive_recv.rb
deleted file mode 100644
index d1fa854..0000000
--- a/examples/ruby/messenger/passive_recv.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-require 'qpid_proton'
-require 'optparse'
-
-addresses = []
-
-OptionParser.new do |opts|
-  opts.banner = "Usage: recv.rb <addr1> ... <addrn>"
-  opts.parse!
-
-  addresses = ARGV
-end
-
-addresses = ["~0.0.0.0"] if addresses.empty?
-
-messenger = Qpid::Proton::Messenger::Messenger.new
-messenger.passive = true
-
-begin
-  messenger.start
-rescue ProtonError => error
-  puts "ERROR: #{error.message}"
-  puts error.backtrace.join("\n")
-  exit
-end
-
-addresses.each do |address|
-  begin
-    messenger.subscribe(address)
-  rescue Qpid::Proton::ProtonError => error
-    puts "ERROR: #{error.message}"
-    exit
-  end
-end
-
-msg = Qpid::Proton::Message.new
-
-read_array = []
-write_array = []
-selectables = {}
-
-loop do
-
-  # wait for incoming messages
-  sel = messenger.selectable
-  while !sel.nil?
-    if sel.terminal?
-      selectables.delete(sel.fileno)
-      read_array.delete(sel)
-      write_array.delete(sel)
-      sel.free
-    else
-      sel.capacity
-      sel.pending
-      if !sel.registered?
-        read_array << sel
-        write_array << sel
-        selectables[sel.fileno] = sel
-        sel.registered = true
-      end
-    end
-    sel = messenger.selectable
-  end
-
-  unless selectables.empty?
-    rarray = []; read_array.each {|fd| rarray << fd.to_io }
-    warray = []; write_array.each {|fd| warray << fd.to_io }
-
-    if messenger.deadline > 0.0
-      result = IO.select(rarray, warray, nil, messenger.deadline)
-    else
-      result = IO.select(rarray, warray)
-    end
-
-    unless result.nil? && result.empty?
-      result.flatten.each do |io|
-        sel = selectables[io.fileno]
-
-        sel.writable if sel.pending > 0
-        sel.readable if sel.capacity > 0
-      end
-    end
-
-    begin
-      messenger.receive(10)
-    rescue Qpid::Proton::ProtonError => error
-      puts "ERROR: #{error.message}"
-      exit
-    end
-
-    while messenger.incoming.nonzero?
-      begin
-        messenger.get(msg)
-      rescue Qpid::Proton::Error => error
-        puts "ERROR: #{error.message}"
-        exit
-      end
-
-      puts "Address: #{msg.address}"
-      subject = msg.subject || "(no subject)"
-      puts "Subject: #{subject}"
-      puts "Body: #{msg.body}"
-      puts "Properties: #{msg.properties}"
-      puts "Instructions: #{msg.instructions}"
-      puts "Annotations: #{msg.annotations}"
-
-      if msg.reply_to
-        puts "=== Sending a reply to #{msg.reply_to}"
-        reply = Qpid::Proton::Message.new
-        reply.address = msg.reply_to
-        reply.subject = "RE: #{msg.subject}"
-        reply.content = "Thanks for the message!"
-
-        messenger.put(reply)
-        messenger.send
-      end
-    end
-  end
-end
-
-messenger.stop
-


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


[4/4] qpid-proton git commit: PROTON-898: Update Ruby bindings to use pn_selectable_get_fd

Posted by mc...@apache.org.
PROTON-898: Update Ruby bindings to use pn_selectable_get_fd

Also removed references to pending and capacity.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/caaabb7b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/caaabb7b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/caaabb7b

Branch: refs/heads/master
Commit: caaabb7bd225aae8d3699ce138ef43c1083782a6
Parents: b49e518
Author: Darryl L. Pierce <mc...@gmail.com>
Authored: Mon Jun 1 13:48:09 2015 -0400
Committer: Darryl L. Pierce <mc...@gmail.com>
Committed: Thu Jun 4 09:11:58 2015 -0400

----------------------------------------------------------------------
 examples/ruby/messenger/nonblocking_recv.rb        | 7 ++-----
 proton-c/bindings/ruby/lib/messenger/selectable.rb | 2 +-
 2 files changed, 3 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/caaabb7b/examples/ruby/messenger/nonblocking_recv.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/messenger/nonblocking_recv.rb b/examples/ruby/messenger/nonblocking_recv.rb
index 2868b52..09dc3f9 100644
--- a/examples/ruby/messenger/nonblocking_recv.rb
+++ b/examples/ruby/messenger/nonblocking_recv.rb
@@ -76,8 +76,6 @@ loop do
       write_array.delete(sel)
       sel.free
     else
-      sel.capacity
-      sel.pending
       if !sel.registered?
         read_array << sel
         write_array << sel
@@ -102,8 +100,8 @@ loop do
       result.flatten.each do |io|
         sel = selectables[io.fileno]
 
-        sel.writable if sel.pending > 0
-        sel.readable if sel.capacity > 0
+        sel.writable
+        sel.readable
       end
     end
 
@@ -145,4 +143,3 @@ loop do
 end
 
 messenger.stop
-

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/caaabb7b/proton-c/bindings/ruby/lib/messenger/selectable.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/messenger/selectable.rb b/proton-c/bindings/ruby/lib/messenger/selectable.rb
index 9a61317..ec5174f 100644
--- a/proton-c/bindings/ruby/lib/messenger/selectable.rb
+++ b/proton-c/bindings/ruby/lib/messenger/selectable.rb
@@ -44,7 +44,7 @@ module Qpid::Proton::Messenger
     # This can be used in conjunction with the IO class.
     #
     def fileno
-      Cproton.pn_selectable_fd(@impl)
+      Cproton.pn_selectable_get_fd(@impl)
     end
 
     def to_io


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


[3/4] qpid-proton git commit: PROTON-897: Enhanced the Ruby nonblocking_recv.rb example

Posted by mc...@apache.org.
PROTON-897: Enhanced the Ruby nonblocking_recv.rb example


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b49e5185
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b49e5185
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b49e5185

Branch: refs/heads/master
Commit: b49e5185c3ffe4a935ba51e4ce4a0e6f5f3ec172
Parents: 267072d
Author: Darryl L. Pierce <mc...@gmail.com>
Authored: Thu Jun 4 08:29:09 2015 -0400
Committer: Darryl L. Pierce <mc...@gmail.com>
Committed: Thu Jun 4 08:29:09 2015 -0400

----------------------------------------------------------------------
 examples/ruby/messenger/nonblocking_recv.rb | 34 +++++++++++++++---------
 1 file changed, 21 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b49e5185/examples/ruby/messenger/nonblocking_recv.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/messenger/nonblocking_recv.rb b/examples/ruby/messenger/nonblocking_recv.rb
index d1fa854..2868b52 100644
--- a/examples/ruby/messenger/nonblocking_recv.rb
+++ b/examples/ruby/messenger/nonblocking_recv.rb
@@ -20,6 +20,14 @@
 require 'qpid_proton'
 require 'optparse'
 
+Thread.new do
+  print "This is a side thread:\n"
+  loop do
+    print "The time is now #{Time.new.strftime('%I:%M:%S')}.\n"
+    sleep 1
+  end
+end
+
 addresses = []
 
 OptionParser.new do |opts|
@@ -37,8 +45,8 @@ messenger.passive = true
 begin
   messenger.start
 rescue ProtonError => error
-  puts "ERROR: #{error.message}"
-  puts error.backtrace.join("\n")
+  print "ERROR: #{error.message}\n"
+  print error.backtrace.join("\n")
   exit
 end
 
@@ -46,7 +54,7 @@ addresses.each do |address|
   begin
     messenger.subscribe(address)
   rescue Qpid::Proton::ProtonError => error
-    puts "ERROR: #{error.message}"
+    print "ERROR: #{error.message}\n"
     exit
   end
 end
@@ -102,7 +110,7 @@ loop do
     begin
       messenger.receive(10)
     rescue Qpid::Proton::ProtonError => error
-      puts "ERROR: #{error.message}"
+      print "ERROR: #{error.message}\n"
       exit
     end
 
@@ -110,24 +118,24 @@ loop do
       begin
         messenger.get(msg)
       rescue Qpid::Proton::Error => error
-        puts "ERROR: #{error.message}"
+        print "ERROR: #{error.message}\n"
         exit
       end
 
-      puts "Address: #{msg.address}"
+      print "Address: #{msg.address}\n"
       subject = msg.subject || "(no subject)"
-      puts "Subject: #{subject}"
-      puts "Body: #{msg.body}"
-      puts "Properties: #{msg.properties}"
-      puts "Instructions: #{msg.instructions}"
-      puts "Annotations: #{msg.annotations}"
+      print "Subject: #{subject}\n"
+      print "Body: #{msg.body}\n"
+      print "Properties: #{msg.properties}\n"
+      print "Instructions: #{msg.instructions}\n"
+      print "Annotations: #{msg.annotations}\n"
 
       if msg.reply_to
-        puts "=== Sending a reply to #{msg.reply_to}"
+        print "=== Sending a reply to #{msg.reply_to}\n"
         reply = Qpid::Proton::Message.new
         reply.address = msg.reply_to
         reply.subject = "RE: #{msg.subject}"
-        reply.content = "Thanks for the message!"
+        reply.body = "Thanks for the message!"
 
         messenger.put(reply)
         messenger.send


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


[2/4] qpid-proton git commit: PROTON-897: Enhance the Ruby examples and README file.

Posted by mc...@apache.org.
PROTON-897: Enhance the Ruby examples and README file.

Added README.md with the goal of turning the examples into a simple
conversation about how to use the Ruby examples.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/ac4731f1
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/ac4731f1
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/ac4731f1

Branch: refs/heads/master
Commit: ac4731f194a4054525938699475d41398f86fdcb
Parents: 89ef63b
Author: Darryl L. Pierce <mc...@gmail.com>
Authored: Tue May 26 15:33:04 2015 -0400
Committer: Darryl L. Pierce <mc...@gmail.com>
Committed: Thu Jun 4 08:28:46 2015 -0400

----------------------------------------------------------------------
 examples/ruby/messenger/README.md | 163 +++++++++++++++++++++++++++++++++
 1 file changed, 163 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ac4731f1/examples/ruby/messenger/README.md
----------------------------------------------------------------------
diff --git a/examples/ruby/messenger/README.md b/examples/ruby/messenger/README.md
new file mode 100644
index 0000000..7cc8dee
--- /dev/null
+++ b/examples/ruby/messenger/README.md
@@ -0,0 +1,163 @@
+## Simple Messenger Examples
+
+The Messenger APIs, contained in the Qpid::Proton::Messenger class, represent the simplest means for sending and receive messages. An application need only create an instance of Messenger to have an endpoint for sending and receiving messages.
+
+Example applications, currently located in the messenger subdirectory, include:
+
+* **send.rb** - Sends one or more messages to a specific address.
+* **recv.rb** - Listens for messages sent to one or more addresses.
+
+### Sending A Simple Message Directly (Without A Broker)
+
+The goal of this example is to demonstrate how to send and receive messages directly between applications. To do that we've broken out the examples into two applciations: **send.rb** and **recv.rb**.
+
+First we need to start the receiver who will listen for an incoming connection:
+
+```
+ $ ruby recv.rb ~0.0.0.0:8888
+```
+
+**NOTE:** Be sure to include the **tilda (~)** at the beginning of each address to be used. This tells the Messenger that it's going to be listening for connections on that port. And be sure to pick a free port for each of the addresses used.
+
+Now you can send messages with:
+
+```
+ $ ruby send.rb -a 0.0.0.0:8888 "Hello world"
+```
+
+**NOTE:** Here you *don't* use a **tilda (~)** at the beginning of the address since you're specifying the receiver address rather than the address on which to listen.
+
+On the receiver side you should see something like:
+
+```
+Address: 0.0.0.0:8888
+Subject: How are you?
+Body: This is a test.
+Properties: {"sent"=>1432651492, "hostname"=>"mcpierce-laptop"}
+Instructions: {"fold"=>"yes", "spindle"=>"no", "mutilate"=>"no"}
+Annotations: {"version"=>1.0, "pill"=>"RED"}
+
+```
+
+This tells us the message we received as expected.
+
+### Sending A Simple Message Through A Broker
+
+To send a message via an intermediary, such as the Qpid broker, we need to give both the sender and the receiver a little bit more information, such as the hostname and port for the broker and the name of the queue where messages will be sent and received.
+
+If you're using the Qpid broker, this can be done using the **qpid-config**
+tool. Simply start your broker and then create our queue, which we'll call "examples":
+
+```
+ $ qpid-config add queue examples
+```
+
+As of this point you can begin sending messages *without* starting the receiver. This is the benefit of using a broker, the ability to have something store messages for retrieval.
+
+Now let's send a bunch of messages to the queue using **send.rb**:
+
+```
+ $ for which in $(seq 1 10); do ruby send.rb --address amqp://localhost/examples "This is test ${which}."; done
+```
+
+This example sends 10 messages to the our queue on the broker, where they will stay until retrieved.
+
+With this scenario we needed to specify the hostname of the broker and also the name of the queue in the address. After the sending completes you can verify the content of the queue using the **qpid-stat** command:
+
+```
+$ qpid-stat -q
+Queues
+  queue                                     dur  autoDel  excl  msg   msgIn  msgOut  bytes  bytesIn  bytesOut  cons  bind
+  =========================================================================================================================
+  examples                                                        10    10      0    2.65k  2.65k       0         0     1
+  fa4b8acb-03b6-4cff-9277-eeb2efe3c88a:0.0       Y        Y        0     0      0       0      0        0         1     2
+```
+
+Now to retrieve the messages. Start the **recv.rb** example using:
+
+```
+$ ruby recv.rb "amqp://127.0.0.1:5672/examples"
+```
+
+Once it connects to the broker, it will subscribe to the queue and begin receiving messages. You should see something like the following:
+
+```
+Address: amqp://localhost/examples
+Subject: How are you?
+Body: This is test 1.
+Properties: {"sent"=>1432837902, "hostname"=>"mcpierce-laptop"}
+Instructions: {"fold"=>"yes", "spindle"=>"no", "mutilate"=>"no"}
+Annotations: {"version"=>1.0, "pill"=>"RED"}
+Address: amqp://localhost/examples
+Subject: How are you?
+Body: This is test 2.
+Properties: {"sent"=>1432837903, "hostname"=>"mcpierce-laptop"}
+Instructions: {"fold"=>"yes", "spindle"=>"no", "mutilate"=>"no"}
+Annotations: {"version"=>1.0, "pill"=>"RED"}
+Address: amqp://localhost/examples
+Subject: How are you?
+Body: This is test 3.
+... truncating the remainder of the output ...
+```
+
+As with the sending, we specific the protocol to use and the address and port on the host to connect to the broker.
+
+##  Non-Blocking Receive With The Messenger APIs
+
+One of the downsides of Messenger is that, out of the box, it's a blocking set of APIs; i.e., when attempting to receive messages the Ruby VM is halted until the call returns.
+
+Enter **non-blocking mode**!
+
+When working in non-blocking mode you set a flag on your messenger to put it into non-blocking mode.
+
+```
+messenger = Qpid::Proton::Messenger.new
+messenger.passive = true
+```
+
+At this point the application is responsible for monitoring the set of file descriptors associated with those Messengers. It takes a little more code but the benefit is that the application can spawn this in a separate thread and not have the entire VM block during I/O operations. The **nonblocking_recv.rb** example app demonstrates how to perform this properly, how to wrap the file descriptor in a Selectable type, monitor it for when there's data to send or receive and then work with the instance of Messenger.
+
+For more details on how to do this, take a look at the comments in the example application.
+
+
+### Running The Non-Blocking Receiver
+
+To start the non-blocking receiver, simply start the example application like this:
+
+```
+ $ ruby nonblocking_recv.rb ~0.0.0.0:8888
+ This is a side thread:
+The time is now 11:39:24.
+The time is now 11:39:25.
+The time is now 11:39:26.
+```
+
+As the receiver runs it outputs the current time every second to show that a separate thread is running.
+
+Now you can launch the **client.rb** example to send a message to the receiver and then wait for a reply:
+
+```
+ $ ruby client.rb -r "~/#" 0.0.0.0:8888 "This is a test." "Here is my message."
+ amqp://c19f3e88-866a-46ae-8284-d229acf8a5cb/#, RE: This is a test.
+```
+
+As you see, in the command line we specify "~/#" as the address to which any reply should be sent. It's outside of the scope of this example, but the tilda (~) is expanded into a unique address by Proton and used for receiving any responses.
+
+On the receiver side you should see something like this:
+
+```
+The time is now 11:42:04.
+The time is now 11:42:05.
+The time is now 11:42:06.
+Address: 0.0.0.0:8888
+Subject: This is a test.
+Body:
+Properties: {}
+Instructions: {}
+Annotations: {}
+=== Sending a reply to amqp://c19f3e88-866a-46ae-8284-d229acf8a5cb/#
+The time is now 11:42:07.
+The time is now 11:42:08.
+```
+
+Notice in the receiver's output how the reply was sent to the address on the sender that was created by our specifying "~/#"


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