amqplib Documentation

repository·main·Indexed 26 days ago

https://github.com/amqp-node/amqplib

A robust AMQP 0-9-1 client library for Node.js, compatible with RabbitMQ. It provides both Promise-based and Callback-based APIs for managing connections, channels, queues, and exchanges. Features include support for RabbitMQ stream queues (version 3.9+), opt-in automatic connection recovery with configurable backoff, and specialized error handling via the 'handler-error' event.

Tokens
9K
Snippets
10
Records
50
Agent score
86%

What's inside amqplib

  1. Overview of RabbitMQ tutorials

    main

    The amqplib tutorials provide practical examples of common RabbitMQ patterns. These include:

    • Hello World!: A basic example with one script sending a message to a queue and another receiving it.
    • Work Queues: Using RabbitMQ to distribute tasks among multiple workers.
    • Publish/Subscribe: Using a fanout exchange to broadcast messages to all subscribers.
    • Routing: Using direct exchanges to route messages based on specific severities.
    • Topics: Using topic exchanges for routing with wildcarded patterns.
    • RPC (Remote Procedure Call): Using RabbitMQ as an intermediary to queue requests and route replies back to clients.
  2. Configure Opt-in Connection Recovery

    main

    Automatic recovery can be enabled by passing a recovery object in the options of amqplib.connect(). This allows the client to automatically attempt to reconnect and recreate the topology (queues, exchanges, consumers) after a connection loss.

    Key options for the recovery object:

    • initialDelay: Initial delay in ms before first retry.
    • maxDelay: Maximum delay in ms between retries.
    • factor: Multiplier for the delay between retries.
    • jitter: Randomness factor applied to the delay.
    • maxRetries: Maximum number of reconnection attempts (Infinity for unlimited).
    • async setup(model): An async function called after every successful (re)connect. Use this to recreate your topology (e.g., assertQueue, consume).
    const amqplib = require('amqplib');
    
    const connection = await amqplib.connect('amqp://localhost', {
      recovery: {
        initialDelay: 200, // ms
        maxDelay: 5000, // ms
        factor: 2,
        jitter: 0.2,
        maxRetries: Infinity,
        async setup(model) {
          // Called after every successful (re)connect.
          // Recreate topology/consumers here.
          const ch = await model.createChannel();
          await ch.assertQueue('tasks', {durable: true});
        },
      },
    });
    
    connection.on('connect', () => {
      console.log('connected');
    });
    
    connection.on('disconnect', (err) => {
      console.warn('disconnected', err.message);
    });
  3. Manage connection blocking status

    main
    AMQP connections can be blocked by the server (e.g., due to resource alarms). When a connection is blocked, the library will prevent sending further frames. You can monitor this state via the 'blocked' and 'unblocked' events.
  4. Handle user-defined event errors with `handler-error`

    main

    If a synchronous error is thrown inside one of your event listeners (e.g., conn.on('message', ...)), it can cause the connection or channel to close or be swallowed.

    To prevent this, register a handler-error listener on both the connection and each channel. The handler-error event is emitted when your own event listener throws an error. This is distinct from the error event, which is emitted by amqplib for protocol-level errors.

    • error event: Emitted by amqplib for protocol errors.
    • handler-error event: Emitted when a user-supplied handler throws. Receives (err, event) where event is the name of the event whose handler threw.
    const connection = await amqp.connect('amqp://localhost');
    
    connection.on('error', (err) => { /* handle protocol errors */ });
    connection.on('handler-error', (err, event) => {
      console.error(`Uncaught exception in connection ${event} listener:`, err);
    });
    
    const channel = await connection.createChannel();
    
    channel.on('error', (err) => { /* handle protocol errors */ });
    channel.on('handler-error', (err, event) => {
      console.error(`Uncaught exception in channel ${event} listener:`, err);
    });
  5. Use the Promise/Async API

    main

    The Promise/Async API is the standard way to use amqplib with modern async/await syntax. It provides methods for connecting to an AMQP server, creating channels, asserting queues, consuming messages, and sending messages to queues.

    const amqplib = require('amqplib');
    
    (async () => {
      const queue = 'tasks';
      const conn = await amqplib.connect('amqp://localhost');
      conn.on('error', (err) => { console.error('Connection error:', err); });
      conn.on('handler-error', (err, event) => { console.error(`Uncaught exception in connection ${event} listener:`, err); });
    
      const ch1 = await conn.createChannel();
      ch1.on('error', (err) => { console.error('Channel error:', err); });
      ch1.on('handler-error', (err, event) => { console.error(`Uncaught exception in channel ${event} listener:`, err); });
      await ch1.assertQueue(queue);
    
      // Listener
      ch1.consume(queue, (msg) => {
        if (msg !== null) {
          console.log('Received:', msg.content.toString());
          ch1.ack(msg);
        } else {
          console.log('Consumer cancelled by server');
        }
      });
    
      // Sender
      const ch2 = await conn.createChannel();
      ch2.on('error', (err) => { console.error('Channel error:', err); });
      ch2.on('handler-error', (err, event) => { console.error(`Uncaught exception in channel ${event} listener:`, err); });
    
      setInterval(() => {
        ch2.sendToQueue(queue, Buffer.from('something to do'));
      }, 1000);
    })();
  6. Use the Callback API

    main

    For legacy codebases or specific requirements, amqplib provides a callback-based API via the amqplib/callback_api module.

    const amqplib = require('amqplib/callback_api');
    const queue = 'tasks';
    
    amqplib.connect('amqp://localhost', (err, conn) => {
      if (err) throw err;
    
      conn.on('error', (err) => { console.error('Connection error:', err); });
      conn.on('handler-error', (err, event) => { console.error(`Uncaught exception in connection ${event} listener:`, err); });
    
      // Listener
      conn.createChannel((err, ch2) => {
        if (err) throw err;
    
        ch2.on('error', (err) => { console.error('Channel error:', err); });
        ch2.on('handler-error', (err, event) => { console.error(`Uncaught exception in channel ${event} listener:`, err); });
    
        ch2.assertQueue(queue);
    
        ch2.consume(queue, (msg) => {
          if (msg !== null) {
            console.log(msg.content.toString());
            ch2.ack(msg);
          } else {
            console.log('Consumer cancelled by server');
          }
        });
      });
    
      // Sender
      conn.createChannel((err, ch1) => {
        if (err) throw err;
    
        ch1.on('error', (err) => { console.error('Channel error:', err); });
        ch1.on('handler-error', (err, event) => { console.error(`Uncaught exception in channel ${event} listener:`, err); });
        ch1.assertQueue(queue);
    
        setInterval(() => {
          ch1.sendToQueue(queue, Buffer.from('something to do'));
        }, 1000);
      });
    });
  7. Configure stream queue consumer offsets

    main

    When consuming from a stream queue, you can specify where to start reading messages using the x-stream-offset argument in the channel.consume options. This allows consumers to attach to the log at specific points (e.g., the beginning, the end, or a specific time).

    channel.consume(queue, onMessage, {
      noAck: false,
      arguments: {
        'x-stream-offset': 'first'
      }
    });