File: README.md

package info (click to toggle)
qpid-proton 0.14.0-5
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 9,632 kB
  • ctags: 20,083
  • sloc: java: 39,624; ansic: 29,389; python: 16,581; cpp: 11,250; ruby: 6,618; perl: 2,641; php: 1,033; xml: 957; sh: 230; pascal: 52; makefile: 32
file content (163 lines) | stat: -rw-r--r-- 6,896 bytes parent folder | download | duplicates (2)
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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 "~/#"