amqplib 0.10.3 → 0.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +7 -4
- package/.github/workflows/test.yml +15 -2
- package/CHANGELOG.md +6 -1
- package/Makefile +3 -4
- package/README.md +1 -1
- package/bin/generate-defs.js +5 -5
- package/examples/direct_reply_to_client.js +22 -0
- package/examples/direct_reply_to_server.js +25 -0
- package/examples/headers.js +29 -31
- package/examples/ssl.js +16 -10
- package/examples/stream_queues/README.md +40 -0
- package/examples/stream_queues/package.json +14 -0
- package/examples/stream_queues/receive_stream.js +55 -0
- package/examples/stream_queues/send_stream.js +38 -0
- package/examples/tutorials/callback_api/emit_log.js +22 -22
- package/examples/tutorials/callback_api/emit_log_direct.js +24 -24
- package/examples/tutorials/callback_api/emit_log_topic.js +23 -20
- package/examples/tutorials/callback_api/new_task.js +21 -20
- package/examples/tutorials/callback_api/receive.js +27 -21
- package/examples/tutorials/callback_api/receive_logs.js +32 -26
- package/examples/tutorials/callback_api/receive_logs_direct.js +42 -41
- package/examples/tutorials/callback_api/receive_logs_topic.js +43 -40
- package/examples/tutorials/callback_api/rpc_client.js +39 -37
- package/examples/tutorials/callback_api/rpc_server.js +42 -32
- package/examples/tutorials/callback_api/send.js +21 -22
- package/examples/tutorials/callback_api/worker.js +29 -25
- package/examples/tutorials/emit_log.js +20 -15
- package/examples/tutorials/emit_log_direct.js +22 -16
- package/examples/tutorials/emit_log_topic.js +22 -15
- package/examples/tutorials/new_task.js +20 -13
- package/examples/tutorials/receive.js +19 -14
- package/examples/tutorials/receive_logs.js +25 -23
- package/examples/tutorials/receive_logs_direct.js +29 -35
- package/examples/tutorials/receive_logs_topic.js +28 -32
- package/examples/tutorials/rpc_client.js +37 -40
- package/examples/tutorials/rpc_server.js +36 -29
- package/examples/tutorials/send.js +26 -18
- package/examples/tutorials/worker.js +27 -21
- package/examples/waitForConfirms.js +18 -19
- package/lib/callback_model.js +295 -290
- package/lib/channel.js +353 -346
- package/lib/channel_model.js +5 -1
- package/lib/codec.js +2 -2
- package/lib/connection.js +542 -527
- package/lib/credentials.js +1 -1
- package/lib/defs.js +2568 -2457
- package/lib/format.js +0 -1
- package/lib/heartbeat.js +32 -29
- package/lib/mux.js +96 -99
- package/package.json +1 -1
- package/test/callback_api.js +182 -174
- package/test/channel_api.js +455 -445
- package/test/codec.js +4 -4
- package/test/frame.js +5 -5
|
@@ -23,15 +23,18 @@ Before reporting a bug or requesting support please...
|
|
|
23
23
|
- https://www.cloudamqp.com/blog/part1-rabbitmq-for-beginners-what-is-rabbitmq.html
|
|
24
24
|
- https://www.rabbitmq.com/tutorials/amqp-concepts.html
|
|
25
25
|
|
|
26
|
-
If the above does not help, please provide the following information...
|
|
26
|
+
If the above does not help, please provide as much of the following information as is relevant...
|
|
27
27
|
|
|
28
|
-
- A clear and concise description of
|
|
28
|
+
- A clear and concise description of the problem
|
|
29
29
|
- RabbitMQ version
|
|
30
30
|
- amqplib version
|
|
31
|
+
- Node.js version
|
|
32
|
+
- The simplest possible code snippet that demonstrates the problem
|
|
33
|
+
- A stack trace
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
Please format code snippets and/or stack traces using GitHub Markdown
|
|
33
36
|
|
|
34
|
-
- https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks
|
|
37
|
+
- https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks).
|
|
35
38
|
|
|
36
39
|
Thank you
|
|
37
40
|
|
|
@@ -14,13 +14,13 @@ jobs:
|
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
15
|
services:
|
|
16
16
|
rabbitmq:
|
|
17
|
-
image: rabbitmq
|
|
17
|
+
image: rabbitmq:3.12-alpine
|
|
18
18
|
ports:
|
|
19
19
|
- 5672:5672
|
|
20
20
|
|
|
21
21
|
strategy:
|
|
22
22
|
matrix:
|
|
23
|
-
node-version: [10.x, 12.x, 14.x, 16.x, 18.x]
|
|
23
|
+
node-version: [10.x, 12.x, 14.x, 16.x, 18.x, 20.x]
|
|
24
24
|
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
25
25
|
|
|
26
26
|
steps:
|
|
@@ -34,5 +34,18 @@ jobs:
|
|
|
34
34
|
# Install all prerequisites
|
|
35
35
|
- run: npm ci
|
|
36
36
|
|
|
37
|
+
# Ensure RabbitMQ is available before continuing
|
|
38
|
+
- run: |
|
|
39
|
+
n=0
|
|
40
|
+
while :
|
|
41
|
+
do
|
|
42
|
+
sleep 5
|
|
43
|
+
echo 'HELO\n\n\n\n' | nc localhost 5672 | grep AMQP
|
|
44
|
+
[[ $? = 0 ]] && break || ((n++))
|
|
45
|
+
(( n >= 5 )) && break
|
|
46
|
+
done
|
|
47
|
+
|
|
48
|
+
- run: echo 'HELO\n\n\n\n' | nc localhost 5672 | grep AMQP
|
|
49
|
+
|
|
37
50
|
# Run the tests
|
|
38
51
|
- run: make test
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Change log for amqplib
|
|
2
2
|
|
|
3
|
+
## Changes in v0.10.4
|
|
4
|
+
|
|
5
|
+
- Improve stream example as per https://github.com/amqp-node/amqplib/issues/722
|
|
6
|
+
- Added support for RabbitMQ's connection update-secret operation. See https://github.com/amqp-node/amqplib/issues/755
|
|
7
|
+
|
|
3
8
|
## Changes in v0.10.3
|
|
4
9
|
|
|
5
10
|
git log v0.10.2..v0.10.3
|
|
@@ -18,7 +23,7 @@
|
|
|
18
23
|
|
|
19
24
|
git log v0.10.0..v0.10.1
|
|
20
25
|
|
|
21
|
-
* Allow servername to be specified via socket options as discussed in
|
|
26
|
+
* Allow servername to be specified via socket options as discussed in
|
|
22
27
|
[issue 697](https://github.com/squaremo/amqp.node/issues/697)
|
|
23
28
|
|
|
24
29
|
## Changes in v0.10.0
|
package/Makefile
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
RABBITMQ_SRC_VERSION=
|
|
1
|
+
RABBITMQ_SRC_VERSION=v3.12.13
|
|
2
2
|
JSON=amqp-rabbitmq-0.9.1.json
|
|
3
|
-
|
|
4
|
-
AMQP_JSON=$(RABBITMQ_CODEGEN)/$(RABBITMQ_SRC_VERSION)/$(JSON)
|
|
3
|
+
AMQP_JSON=https://raw.githubusercontent.com/rabbitmq/rabbitmq-server/$(RABBITMQ_SRC_VERSION)/deps/rabbitmq_codegen/$(JSON)
|
|
5
4
|
|
|
6
|
-
NODEJS_VERSIONS='10.21' '11.15' '12.18' '13.14' '14.5' '15.8' '16.3.0' '18.1.0'
|
|
5
|
+
NODEJS_VERSIONS='10.21' '11.15' '12.18' '13.14' '14.5' '15.8' '16.3.0' '18.1.0' '20.10.0'
|
|
7
6
|
|
|
8
7
|
MOCHA=./node_modules/.bin/mocha
|
|
9
8
|
_MOCHA=./node_modules/.bin/_mocha
|
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ const amqplib = require('amqplib');
|
|
|
87
87
|
// Listener
|
|
88
88
|
ch1.consume(queue, (msg) => {
|
|
89
89
|
if (msg !== null) {
|
|
90
|
-
console.log('
|
|
90
|
+
console.log('Received:', msg.content.toString());
|
|
91
91
|
ch1.ack(msg);
|
|
92
92
|
} else {
|
|
93
93
|
console.log('Consumer cancelled by server');
|
package/bin/generate-defs.js
CHANGED
|
@@ -495,7 +495,7 @@ function decoderFn(method) {
|
|
|
495
495
|
break;
|
|
496
496
|
case 'longstr':
|
|
497
497
|
println('len = buffer.readUInt32BE(offset); offset += 4;');
|
|
498
|
-
println('val = buffer.
|
|
498
|
+
println('val = buffer.subarray(offset, offset + len);');
|
|
499
499
|
println('offset += len;');
|
|
500
500
|
break;
|
|
501
501
|
case 'shortstr':
|
|
@@ -505,7 +505,7 @@ function decoderFn(method) {
|
|
|
505
505
|
break;
|
|
506
506
|
case 'table':
|
|
507
507
|
println('len = buffer.readUInt32BE(offset); offset += 4;');
|
|
508
|
-
println('val = decodeFields(buffer.
|
|
508
|
+
println('val = decodeFields(buffer.subarray(offset, offset + len));');
|
|
509
509
|
println('offset += len;');
|
|
510
510
|
break;
|
|
511
511
|
default:
|
|
@@ -657,7 +657,7 @@ function encodePropsFn(props) {
|
|
|
657
657
|
// size does not include the frame header or frame end byte
|
|
658
658
|
println('buffer.writeUInt32BE(offset - 7, 3);');
|
|
659
659
|
println('buffer.writeUInt16BE(flags, 19);');
|
|
660
|
-
println('return buffer.
|
|
660
|
+
println('return buffer.subarray(0, offset + 1);');
|
|
661
661
|
println('}');
|
|
662
662
|
}
|
|
663
663
|
|
|
@@ -697,7 +697,7 @@ function decodePropsFn(props) {
|
|
|
697
697
|
break;
|
|
698
698
|
case 'longstr':
|
|
699
699
|
println('len = buffer.readUInt32BE(offset); offset += 4;');
|
|
700
|
-
println('val = buffer.
|
|
700
|
+
println('val = buffer.subarray(offset, offset + len);');
|
|
701
701
|
println('offset += len;');
|
|
702
702
|
break;
|
|
703
703
|
case 'shortstr':
|
|
@@ -707,7 +707,7 @@ function decodePropsFn(props) {
|
|
|
707
707
|
break;
|
|
708
708
|
case 'table':
|
|
709
709
|
println('len = buffer.readUInt32BE(offset); offset += 4;');
|
|
710
|
-
println('val = decodeFields(buffer.
|
|
710
|
+
println('val = decodeFields(buffer.subarray(offset, offset + len));');
|
|
711
711
|
println('offset += len;');
|
|
712
712
|
break;
|
|
713
713
|
default:
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const amqp = require('../');
|
|
4
|
+
|
|
5
|
+
const queue = 'rpc_queue';
|
|
6
|
+
|
|
7
|
+
(async () => {
|
|
8
|
+
const connection = await amqp.connect();
|
|
9
|
+
const channel = await connection.createChannel();
|
|
10
|
+
|
|
11
|
+
await channel.consume('amq.rabbitmq.reply-to', async (message) => {
|
|
12
|
+
console.log(message.content.toString());
|
|
13
|
+
await channel.close();
|
|
14
|
+
await connection.close();
|
|
15
|
+
}, { noAck: true });
|
|
16
|
+
|
|
17
|
+
await channel.assertQueue(queue, { durable: false });
|
|
18
|
+
|
|
19
|
+
channel.sendToQueue(queue, Buffer.from(' [X] ping'), {
|
|
20
|
+
replyTo: 'amq.rabbitmq.reply-to',
|
|
21
|
+
});
|
|
22
|
+
})();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const amqp = require('../');
|
|
4
|
+
const { v4: uuid } = require('uuid');
|
|
5
|
+
|
|
6
|
+
const queue = 'rpc_queue';
|
|
7
|
+
|
|
8
|
+
(async () => {
|
|
9
|
+
const connection = await amqp.connect();
|
|
10
|
+
const channel = await connection.createChannel();
|
|
11
|
+
|
|
12
|
+
process.once('SIGINT', async () => {
|
|
13
|
+
await channel.close();
|
|
14
|
+
await connection.close();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
await channel.assertQueue(queue, { durable: false });
|
|
18
|
+
await channel.consume(queue, (message) => {
|
|
19
|
+
console.log(message.content.toString());
|
|
20
|
+
channel.sendToQueue(message.properties.replyTo, Buffer.from(' [.] pong'));
|
|
21
|
+
}, { noAck: true });
|
|
22
|
+
|
|
23
|
+
console.log(' [x] To exit press CTRL+C.');
|
|
24
|
+
|
|
25
|
+
})();
|
package/examples/headers.js
CHANGED
|
@@ -1,25 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
amqp.connect()
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
ch.assertExchange('matching exchange', 'headers').then(function(ex) {
|
|
14
|
-
ch.assertQueue().then(function(q) {
|
|
15
|
-
bindAndConsume(ch, ex, q).then(function() {
|
|
16
|
-
send(ch, ex);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
3
|
+
const amqp = require('../');
|
|
4
|
+
|
|
5
|
+
(async () => {
|
|
6
|
+
|
|
7
|
+
const connection = await amqp.connect();
|
|
8
|
+
const channel = await connection.createChannel();
|
|
9
|
+
|
|
10
|
+
process.once('SIGINT', async () => {
|
|
11
|
+
await channel.close();
|
|
12
|
+
await connection.close();
|
|
19
13
|
});
|
|
20
|
-
}
|
|
21
14
|
|
|
22
|
-
|
|
15
|
+
const { exchange } = await channel.assertExchange('matching exchange', 'headers');
|
|
16
|
+
const { queue } = await channel.assertQueue();
|
|
17
|
+
|
|
23
18
|
// When using a headers exchange, the headers to be matched go in
|
|
24
19
|
// the binding arguments. The routing key is ignore, so best left
|
|
25
20
|
// empty.
|
|
@@ -27,16 +22,19 @@ function bindAndConsume(ch, ex, q) {
|
|
|
27
22
|
// 'x-match' is 'all' or 'any', meaning "all fields must match" or
|
|
28
23
|
// "at least one field must match", respectively. The values to be
|
|
29
24
|
// matched go in subsequent fields.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
25
|
+
await channel.bindQueue(queue, exchange, '', {
|
|
26
|
+
'x-match': 'any',
|
|
27
|
+
'foo': 'bar',
|
|
28
|
+
'baz': 'boo'
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
await channel.consume(queue, (message) => {
|
|
32
|
+
console.log(message.content.toString());
|
|
33
|
+
}, { noAck: true });
|
|
34
|
+
|
|
35
|
+
channel.publish(exchange, '', Buffer.from('hello'), { headers: { baz: 'boo' }});
|
|
36
|
+
channel.publish(exchange, '', Buffer.from('hello'), { headers: { foo: 'bar' }});
|
|
37
|
+
channel.publish(exchange, '', Buffer.from('lost'), { headers: { meh: 'nah' }});
|
|
38
|
+
|
|
39
|
+
console.log(' [x] To exit press CTRL+C.');
|
|
40
|
+
})();
|
package/examples/ssl.js
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
//
|
|
19
19
|
// openssl s_client -connect localhost:5671
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
const amqp = require('../');
|
|
22
|
+
const fs = require('fs');
|
|
23
23
|
|
|
24
24
|
// Assemble the SSL options; for verification we need at least
|
|
25
25
|
// * a certificate to present to the server ('cert', in PEM format)
|
|
@@ -34,7 +34,7 @@ var fs = require('fs');
|
|
|
34
34
|
// to use `rejectUnauthorized: false`.
|
|
35
35
|
|
|
36
36
|
// Options for full client and server verification:
|
|
37
|
-
|
|
37
|
+
const opts = {
|
|
38
38
|
cert: fs.readFileSync('../etc/client/cert.pem'),
|
|
39
39
|
key: fs.readFileSync('../etc/client/key.pem'),
|
|
40
40
|
// cert and key or
|
|
@@ -49,16 +49,22 @@ var opts = {
|
|
|
49
49
|
// {verify, verify_none},
|
|
50
50
|
// {fail_if_no_peer_cert,false}
|
|
51
51
|
//
|
|
52
|
-
//
|
|
52
|
+
// const opts = { ca: [fs.readFileSync('../etc/testca/cacert.pem')] };
|
|
53
53
|
|
|
54
54
|
// Option to use the SSL client certificate for authentication
|
|
55
55
|
// opts.credentials = amqp.credentials.external();
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
(async () => {
|
|
58
|
+
const connection = await amqp.connect('amqp://localhost', opts);
|
|
59
|
+
const channel = await connection.createChannel();
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
ch.sendToQueue('foo', Buffer.from('Hello World!'));
|
|
61
|
+
process.on('SIGINT', async () => {
|
|
62
|
+
await channel.close();
|
|
63
|
+
await connection.close();
|
|
63
64
|
});
|
|
64
|
-
|
|
65
|
+
|
|
66
|
+
channel.sendToQueue('foo', Buffer.from('Hello World!'));
|
|
67
|
+
|
|
68
|
+
console.log(' [x] To exit press CTRL+C.');
|
|
69
|
+
})();
|
|
70
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
RabbitMQ Stream Examples
|
|
2
|
+
---
|
|
3
|
+
The [stream queues](https://www.rabbitmq.com/streams.html) are available starting from RabbitMQ 3.9
|
|
4
|
+
|
|
5
|
+
These examples show how to use stream queues with the lib.
|
|
6
|
+
|
|
7
|
+
Send a message to a stream queue
|
|
8
|
+
```
|
|
9
|
+
node send_stream.js
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Receive all the messages from stream queue:
|
|
13
|
+
```
|
|
14
|
+
node receive_stream.js
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Consumers can be configured to receive messages using an offset via the `x-stream-offset` argument. e.g.
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
channel.consume(queue, onMessage, {
|
|
21
|
+
noAck: false,
|
|
22
|
+
arguments: {
|
|
23
|
+
'x-stream-offset': 'first'
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
RabbitMQ supports six different types of offset, however specifying them can be
|
|
29
|
+
|
|
30
|
+
| Offset Type | Example Value | Notes |
|
|
31
|
+
|-----------|----------------------------------------------------------|-------|
|
|
32
|
+
| First | `{'x-stream-offset':'first'}` | Start from the first message in the log |
|
|
33
|
+
| Last | `{'x-stream-offset':'last'}` | Start from the last "chunk" of messages (could be multiple messages) |
|
|
34
|
+
| Next | `{'x-stream-offset':'next'}` | Start from the next message (the default) |
|
|
35
|
+
| Offset | `{'x-stream-offset':5}` | a numerical value specifying an exact offset to attach to the log at |
|
|
36
|
+
| Timestamp | `{'x-stream-offset':{'!':'timestamp',value:1686519750}}` | a timestamp value specifying the point in time to attach to the log at. The timestamp must be the number of seconds since 00:00:00 UTC, 1970-01-01. Consumers can receive messages published a bit before the specified timestamp. |
|
|
37
|
+
| Interval | `{'x-stream-offset':'1h'}` | the time interval relative to current time to attach the log at. Valid units are Y, M, D, h, m and s |
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
See https://www.rabbitmq.com/streams.html#consuming for more details
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "stream_queues",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "An example demonstrating use of stream queues",
|
|
5
|
+
"main": "n",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"amqplib": "^0.10.3"
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
12
|
+
},
|
|
13
|
+
"license": "ISC"
|
|
14
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const amqp = require('amqplib');
|
|
2
|
+
|
|
3
|
+
(async () => {
|
|
4
|
+
try {
|
|
5
|
+
const connection = await amqp.connect('amqp://localhost');
|
|
6
|
+
process.once('SIGINT', connection.close);
|
|
7
|
+
|
|
8
|
+
const channel = await connection.createChannel();
|
|
9
|
+
const queue = 'my_first_stream';
|
|
10
|
+
|
|
11
|
+
// Define the queue stream
|
|
12
|
+
// Mandatory: exclusive: false, durable: true autoDelete: false
|
|
13
|
+
await channel.assertQueue(queue, {
|
|
14
|
+
exclusive: false,
|
|
15
|
+
durable: true,
|
|
16
|
+
autoDelete: false,
|
|
17
|
+
arguments: {
|
|
18
|
+
'x-queue-type': 'stream', // Mandatory to define stream queue
|
|
19
|
+
'x-max-length-bytes': 2_000_000_000 // Set the queue retention to 2GB else the stream doesn't have any limit
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
channel.qos(100); // This is mandatory
|
|
24
|
+
|
|
25
|
+
channel.consume(queue, (msg) => {
|
|
26
|
+
console.log(" [x] Received '%s'", msg.content.toString());
|
|
27
|
+
channel.ack(msg); // Mandatory
|
|
28
|
+
}, {
|
|
29
|
+
noAck: false,
|
|
30
|
+
arguments: {
|
|
31
|
+
/*
|
|
32
|
+
Here you can specify the offset: : first, last, next, offset, timestamp and interval, i.e.
|
|
33
|
+
|
|
34
|
+
'x-stream-offset': 'first'
|
|
35
|
+
'x-stream-offset': 'last'
|
|
36
|
+
'x-stream-offset': 'next'
|
|
37
|
+
'x-stream-offset': 5
|
|
38
|
+
'x-stream-offset': { '!': 'timestamp', value: 1686519750 }
|
|
39
|
+
'x-stream-offset': '1h'
|
|
40
|
+
|
|
41
|
+
The timestamp must be the desired number of seconds since 00:00:00 UTC, 1970-01-01
|
|
42
|
+
The interval units can be Y, M, D, h, m, s
|
|
43
|
+
|
|
44
|
+
*/
|
|
45
|
+
'x-stream-offset': 'first'
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
console.log(' [*] Waiting for messages. To exit press CTRL+C');
|
|
50
|
+
}
|
|
51
|
+
// Catch and display any errors in the console
|
|
52
|
+
catch(e) {
|
|
53
|
+
console.log(e)
|
|
54
|
+
}
|
|
55
|
+
})();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const amqp = require('amqplib');
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
(async () => {
|
|
5
|
+
try {
|
|
6
|
+
const connection = await amqp.connect('amqp://localhost');
|
|
7
|
+
process.once('SIGINT', connection.close);
|
|
8
|
+
|
|
9
|
+
const channel = await connection.createChannel();
|
|
10
|
+
const queue = 'my_first_stream';
|
|
11
|
+
const msg = `Hello World! ${Date.now()}`;
|
|
12
|
+
|
|
13
|
+
// Define the queue stream
|
|
14
|
+
// Mandatory: exclusive: false, durable: true autoDelete: false
|
|
15
|
+
await channel.assertQueue(queue, {
|
|
16
|
+
exclusive: false,
|
|
17
|
+
durable: true,
|
|
18
|
+
autoDelete: false,
|
|
19
|
+
arguments: {
|
|
20
|
+
'x-queue-type': 'stream', // Mandatory to define stream queue
|
|
21
|
+
'x-max-length-bytes': 2_000_000_000 // Set the queue retention to 2GB else the stream doesn't have any limit
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Send the message to the stream queue
|
|
26
|
+
await channel.sendToQueue(queue, Buffer.from(msg));
|
|
27
|
+
console.log(" [x] Sent '%s'", msg);
|
|
28
|
+
await channel.close();
|
|
29
|
+
|
|
30
|
+
// Close connection
|
|
31
|
+
connection.close();
|
|
32
|
+
}
|
|
33
|
+
// Catch and display any errors in the console
|
|
34
|
+
catch(e) {
|
|
35
|
+
console.log(e)
|
|
36
|
+
}
|
|
37
|
+
})();
|
|
38
|
+
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const amqp = require('amqplib/callback_api');
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if (conn) conn.close(function() { process.exit(1); });
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function on_connect(err, conn) {
|
|
11
|
-
if (err !== null) return bail(err);
|
|
5
|
+
const exchange = 'logs';
|
|
6
|
+
const text = process.argv.slice(2).join(' ') || 'info: Hello World!';
|
|
12
7
|
|
|
13
|
-
|
|
8
|
+
amqp.connect((err, connection) => {
|
|
9
|
+
if (err) return bail(err);
|
|
10
|
+
connection.createChannel((err, channel) => {
|
|
11
|
+
if (err) return bail(err, connection);
|
|
12
|
+
channel.assertExchange(exchange, 'fanout', { durable: false }, (err) => {
|
|
13
|
+
if (err) return bail(err, connection);
|
|
14
|
+
channel.publish(exchange, '', Buffer.from(text));
|
|
15
|
+
console.log(" [x] Sent '%s'", text);
|
|
16
|
+
channel.close(() => {
|
|
17
|
+
connection.close();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
ch.publish(ex, '', Buffer.from(msg));
|
|
21
|
-
console.log(" [x] Sent '%s'", msg);
|
|
22
|
-
ch.close(function() { conn.close(); });
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
conn.createChannel(on_channel_open);
|
|
23
|
+
function bail(err, connection) {
|
|
24
|
+
console.error(err);
|
|
25
|
+
if (connection) connection.close(() => {
|
|
26
|
+
process.exit(1);
|
|
27
|
+
});
|
|
26
28
|
}
|
|
27
|
-
|
|
28
|
-
amqp.connect(on_connect);
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const amqp = require('amqplib/callback_api');
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const exchange = 'direct_logs';
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const routingKey = (args.length > 0) ? args[0] : 'info';
|
|
8
|
+
const text = args.slice(1).join(' ') || 'Hello World!';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
function on_channel_open(err, ch) {
|
|
21
|
-
if (err !== null) return bail(err, conn);
|
|
22
|
-
ch.assertExchange(ex, 'direct', exopts, function(err, ok) {
|
|
23
|
-
ch.publish(ex, severity, Buffer.from(message));
|
|
24
|
-
ch.close(function() { conn.close(); });
|
|
10
|
+
amqp.connect((err, connection) => {
|
|
11
|
+
if (err) return bail(err);
|
|
12
|
+
connection.createChannel((err, channel) => {
|
|
13
|
+
if (err) return bail(err, connection);
|
|
14
|
+
channel.assertExchange(exchange, 'direct', { durable: false }, (err) => {
|
|
15
|
+
if (err) return bail(err, connection);
|
|
16
|
+
channel.publish(exchange, routingKey, Buffer.from(text));
|
|
17
|
+
console.log(" [x] Sent '%s'", text);
|
|
18
|
+
channel.close(() => {
|
|
19
|
+
connection.close();
|
|
20
|
+
});
|
|
25
21
|
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
29
24
|
|
|
30
|
-
|
|
25
|
+
function bail(err, connection) {
|
|
26
|
+
console.error(err);
|
|
27
|
+
if (connection) connection.close(() => {
|
|
28
|
+
process.exit(1);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const amqp = require('amqplib/callback_api');
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const exchange = 'topic_logs';
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const routingKey = (args.length > 0) ? args[0] : 'info';
|
|
8
|
+
const text = args.slice(1).join(' ') || 'Hello World!';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
ch.publish(ex, key, Buffer.from(message));
|
|
21
|
-
console.log(" [x] Sent %s:'%s'", key, message);
|
|
22
|
-
ch.close(function() { conn.close(); });
|
|
10
|
+
amqp.connect((err, connection) => {
|
|
11
|
+
if (err) return bail(err);
|
|
12
|
+
connection.createChannel((err, channel) => {
|
|
13
|
+
if (err) return bail(err, connection);
|
|
14
|
+
channel.assertExchange(exchange, 'topic', { durable: false }, (err) => {
|
|
15
|
+
if (err) return bail(err, connection);
|
|
16
|
+
channel.publish(exchange, routingKey, Buffer.from(text));
|
|
17
|
+
console.log(" [x] Sent '%s'", text);
|
|
18
|
+
channel.close(() => {
|
|
19
|
+
connection.close();
|
|
20
|
+
});
|
|
23
21
|
});
|
|
24
22
|
});
|
|
25
|
-
}
|
|
23
|
+
});
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
function bail(err, connection) {
|
|
26
|
+
console.error(err);
|
|
27
|
+
if (connection) connection.close(() => {
|
|
28
|
+
process.exit(1);
|
|
29
|
+
});
|
|
30
|
+
}
|