Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
rhea-promise
Advanced tools
The rhea-promise npm package is a promise-based wrapper around the rhea library, which is an AMQP 1.0 client for Node.js. It simplifies the process of working with AMQP 1.0 by providing a more modern, promise-based API.
Sending Messages
This feature allows you to send messages to an AMQP 1.0 broker. The code sample demonstrates how to establish a connection, create a sender, send a message, and then close the sender and connection.
const { Connection, Sender } = require('rhea-promise');
async function sendMessage() {
const connection = new Connection({ host: 'localhost', port: 5672 });
await connection.open();
const sender = await connection.createSender({ target: { address: 'queue' } });
await sender.send({ body: 'Hello, World!' });
await sender.close();
await connection.close();
}
sendMessage().catch(console.error);
Receiving Messages
This feature allows you to receive messages from an AMQP 1.0 broker. The code sample demonstrates how to establish a connection, create a receiver, and handle incoming messages.
const { Connection, Receiver } = require('rhea-promise');
async function receiveMessages() {
const connection = new Connection({ host: 'localhost', port: 5672 });
await connection.open();
const receiver = await connection.createReceiver({ source: { address: 'queue' } });
receiver.on('message', (context) => {
console.log('Received message:', context.message.body);
});
}
receiveMessages().catch(console.error);
Request-Response Pattern
This feature allows you to implement a request-response pattern using AMQP 1.0. The code sample demonstrates how to send a request message and handle the response.
const { Connection, Sender, Receiver } = require('rhea-promise');
async function requestResponse() {
const connection = new Connection({ host: 'localhost', port: 5672 });
await connection.open();
const sender = await connection.createSender({ target: { address: 'request_queue' } });
const receiver = await connection.createReceiver({ source: { address: 'response_queue' } });
receiver.on('message', (context) => {
console.log('Received response:', context.message.body);
});
await sender.send({ body: 'Request message' });
}
requestResponse().catch(console.error);
The amqp10 package is another AMQP 1.0 client for Node.js. It provides a similar set of functionalities as rhea-promise but uses a callback-based API instead of promises. This can make the code less readable and harder to manage compared to the promise-based approach of rhea-promise.
The amqplib package is an AMQP 0.9.1 client for Node.js. While it does not support AMQP 1.0, it is widely used for RabbitMQ, which uses AMQP 0.9.1. It provides a callback-based API and is well-documented, making it a good choice for projects that do not require AMQP 1.0.
The rhea package is the underlying library that rhea-promise wraps around. It provides a more low-level, event-driven API for working with AMQP 1.0. While it offers more control and flexibility, it can be more complex to use compared to the promise-based API of rhea-promise.
A Promisified layer over rhea AMQP client.
npm install rhea-promise
You can set the following environment variable to get the debug logs.
export DEBUG=rhea-promise*
export DEBUG=rhea*
DEBUG
environment variable as follows:export DEBUG=rhea*,-rhea:raw,-rhea:message,-rhea-promise:eventhandler,-rhea-promise:translate
DEBUG
environment variable as shown above and then run your test script as follows:
out.log
and logging statement from the sdk go to debug.log
.
node your-test-script.js > out.log 2>debug.log
out.log
by redirecting stderr to stdout (&1), and then redirect stdout to a file:
node your-test-script.js >out.log 2>&1
out.log
.
node your-test-script.js &> out.log
AMQP
, for two peers to communicate successfully, different entities (Container, Connection, Session, Link) need to be created. There is a relationship between those entities.
rhea
propagates those events to its parent entity.
If they are not handled at the Container
level (uber parent), then they are transformed into an error
event. This would cause your
application to crash if there is no listener added for the error
event.rhea-promise
, the library creates, equivalent objects Connection, Session, Sender, Receiver
and wraps objects from rhea
within them.
It adds event listeners to all the possible events that can occur at any level and re-emits those events with the same arguments as one would
expect from rhea. This makes it easy for consumers of rhea-promise
to use the EventEmitter pattern. Users can efficiently use different
event emitter methods like .once()
, .on()
, .prependListeners()
, etc. Since rhea-promise
add those event listeners on rhea
objects,
the errors will never be propagated to the parent entity. This can be good as well as bad depending on what you do.
*_error
events and *_close
events emitted on an entity will not be propagated to it's parent. Thus ensuring that errors are handled at the right level.*_error
and *_close
events at the right level, then you will never know why an entity shutdown.We believe our design enforces good practices to be followed while using the event emitter pattern.
Please take a look at the sample.env file for examples on how to provide the values for different parameters like host, username, password, port, senderAddress, receiverAddress, etc.
Sender
.> ts-node ./examples/send.ts
.NOTE: If you are running the sample with .env
config file, then please run the sample from the directory that contains .env
config file.
import {
Connection, Sender, EventContext, Message, ConnectionOptions, Delivery, SenderOptions
} from "rhea-promise";
import * as dotenv from "dotenv"; // Optional for loading environment configuration from a .env (config) file
dotenv.config();
const host = process.env.AMQP_HOST || "host";
const username = process.env.AMQP_USERNAME || "sharedAccessKeyName";
const password = process.env.AMQP_PASSWORD || "sharedAccessKeyValue";
const port = parseInt(process.env.AMQP_PORT || "5671");
const senderAddress = process.env.SENDER_ADDRESS || "address";
async function main(): Promise<void> {
const connectionOptions: ConnectionOptions = {
transport: "tls",
host: host,
hostname: host,
username: username,
password: password,
port: port,
reconnect: false
};
const connection: Connection = new Connection(connectionOptions);
const senderName = "sender-1";
const senderOptions: SenderOptions = {
name: senderName,
target: {
address: senderAddress
},
onError: (context: EventContext) => {
const senderError = context.sender && context.sender.error;
if (senderError) {
console.log(">>>>> [%s] An error occurred for sender '%s': %O.",
connection.id, senderName, senderError);
}
},
onSessionError: (context: EventContext) => {
const sessionError = context.session && context.session.error;
if (sessionError) {
console.log(">>>>> [%s] An error occurred for session of sender '%s': %O.",
connection.id, senderName, sessionError);
}
}
};
await connection.open();
const sender: Sender = await connection.createSender(senderOptions);
const message: Message = {
body: "Hello World!!",
message_id: "12343434343434"
};
// Please, note that we are not awaiting on sender.send()
// You will notice that `delivery.settled` will be `false`.
const delivery: Delivery = sender.send(message);
console.log(">>>>>[%s] Delivery id: %d, settled: %s",
connection.id,
delivery.id,
delivery.settled);
await sender.close();
await connection.close();
}
main().catch((err) => console.log(err));
AwaitableSender
> ts-node ./examples/awaitableSend.ts
.import {
Connection, Message, ConnectionOptions, Delivery, AwaitableSenderOptions, AwaitableSender
} from "rhea-promise";
import * as dotenv from "dotenv"; // Optional for loading environment configuration from a .env (config) file
dotenv.config();
const host = process.env.AMQP_HOST || "host";
const username = process.env.AMQP_USERNAME || "sharedAccessKeyName";
const password = process.env.AMQP_PASSWORD || "sharedAccessKeyValue";
const port = parseInt(process.env.AMQP_PORT || "5671");
const senderAddress = process.env.SENDER_ADDRESS || "address";
async function main(): Promise<void> {
const connectionOptions: ConnectionOptions = {
transport: "tls",
host: host,
hostname: host,
username: username,
password: password,
port: port,
reconnect: false
};
const connection: Connection = new Connection(connectionOptions);
const senderName = "sender-1";
const awaitableSenderOptions: AwaitableSenderOptions = {
name: senderName,
target: {
address: senderAddress
},
};
await connection.open();
// Notice that we are awaiting on the message being sent.
const sender: AwaitableSender = await connection.createAwaitableSender(
awaitableSenderOptions
);
for (let i = 0; i < 10; i++) {
const message: Message = {
body: `Hello World - ${i}`,
message_id: i
};
// Note: Here we are awaiting for the send to complete.
// You will notice that `delivery.settled` will be `true`, irrespective of whether the promise resolves or rejects.
const delivery: Delivery = await sender.send(message, {
timeoutInSeconds: 10
});
console.log(
"[%s] await sendMessage -> Delivery id: %d, settled: %s",
connection.id,
delivery.id,
delivery.settled
);
}
await sender.close();
await connection.close();
}
main().catch((err) => console.log(err));
> ts-node ./examples/receive.ts
.NOTE: If you are running the sample with .env
config file, then please run the sample from the directory that contains .env
config file.
import {
Connection, Receiver, EventContext, ConnectionOptions, ReceiverOptions, delay, ReceiverEvents
} from "rhea-promise";
import * as dotenv from "dotenv"; // Optional for loading environment configuration from a .env (config) file
dotenv.config();
const host = process.env.AMQP_HOST || "host";
const username = process.env.AMQP_USERNAME || "sharedAccessKeyName";
const password = process.env.AMQP_PASSWORD || "sharedAccessKeyValue";
const port = parseInt(process.env.AMQP_PORT || "5671");
const receiverAddress = process.env.RECEIVER_ADDRESS || "address";
async function main(): Promise<void> {
const connectionOptions: ConnectionOptions = {
transport: "tls",
host: host,
hostname: host,
username: username,
password: password,
port: port,
reconnect: false
};
const connection: Connection = new Connection(connectionOptions);
const receiverName = "receiver-1";
const receiverOptions: ReceiverOptions = {
name: receiverName,
source: {
address: receiverAddress
},
onSessionError: (context: EventContext) => {
const sessionError = context.session && context.session.error;
if (sessionError) {
console.log(">>>>> [%s] An error occurred for session of receiver '%s': %O.",
connection.id, receiverName, sessionError);
}
}
};
await connection.open();
const receiver: Receiver = await connection.createReceiver(receiverOptions);
receiver.on(ReceiverEvents.message, (context: EventContext) => {
console.log("Received message: %O", context.message);
});
receiver.on(ReceiverEvents.receiverError, (context: EventContext) => {
const receiverError = context.receiver && context.receiver.error;
if (receiverError) {
console.log(">>>>> [%s] An error occurred for receiver '%s': %O.",
connection.id, receiverName, receiverError);
}
});
// sleeping for 2 mins to let the receiver receive messages and then closing it.
await delay(120000);
await receiver.close();
await connection.close();
}
main().catch((err) => console.log(err));
git clone https://github.com/amqp/rhea-promise.git
npm i -g typescript
npm i -g ts-node
npm i
npm run build
Amqp protocol specification can be found here.
FAQs
A Promisified layer over rhea AMQP client
The npm package rhea-promise receives a total of 0 weekly downloads. As such, rhea-promise popularity was classified as not popular.
We found that rhea-promise demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.