0

I am building a Typescript package around amqplib's Promise API to make it simpler for me to send messages between two RabbitMQ queues.

This is a method inside a class of said package that is responsible for sending a message to RabbitMQ. It's not actually sending messages, because I can't see them from CloudAMQP.

class PostOffice {
    connection: any;

    constructor(connection: any) {
        this.connection = connection;
    }

    //...

    // TMQMessage is an object that can be trivially serialized to JSON
    // The Writer class holds the channel because I'm having trouble
    // making Typescript class member updates stick after a method returns.
    async send(writer: Writer, message: TMQMessage) {
        //...RabbitMQ code begins here
        let channel = writer.stageConsume[0]; // This channel is created elsewhere
        
        // Queue is created here and I can see it in CloudAMQP.
        await channel.assertQueue(message.to + "/stage/1", {
            durable: true,
        }); // `message.to` is a string indicating destination, e.g. 'test/hello'
        
        // According to docs, the content should be converted to Buffer
        await channel.sendToQueue(message.to + "/stage/1", Buffer.from(JSON.stringify(message)));
        
        channel.close()
    }

}

This is a class I made that creates connections and channels, which is being used here:

import { Writer } from "./Writer";

export class ConnectionFactory {
    url: string;
    amqp: any;
    constructor(url: string) {
        this.url = url;
        this.amqp = require('amqplib');
    }

    async connect(timeout: number = 2000) {
        let connection = await this.amqp.connect(this.url, {
            // timeout for a message acknowledge.
            timeout, // Make the timeout 2s per now
        })
        return connection;
    }
    async createChannels(connection: any, writer: Writer) {
        //... relevant code starts here
        let stageChannels = [];
        stageChannels.push(await connection.createChannel())
        writer.stageConsume = stageChannels;
        return writer;
    }
}

}

My connection factory seems to be working properly, because I can see the connections from CloudAMQP's dashboard. Also I can see the Queues that have been created (asserted in my code) from the dashboard too. However, I am unable to get amqplib to send a message out to CloudAMQP.

Here's the (async) code I'm using to call my package:

let Cf = new ConnectionFactory(url)
let connection = await Cf.connect()
let writer = new Writer();

let message: TMQMessage = {
    //... message content in JSON
}

writer = await Cf.createChannels(connection, writer)
let po = new PostOffice(connection)
await po.send(writer, message)

What seems to be wrong?

Zenul_Abidin
  • 573
  • 8
  • 23

1 Answers1

0

Probably want to await the close method too. But in general I would recommend amqp-client.js (that also have TypeScript definitions), https://github.com/cloudamqp/amqp-client.js/

Carl Hörberg
  • 5,973
  • 5
  • 41
  • 47
  • It looks simple enough. I'll go ahead and migrate my package to use that, and see if things work better then. – Zenul_Abidin Jan 07 '22 at 13:05
  • Typescript's only letting me `import AMQPClient from '@cloudamqp/amqp-client'`, if I try to import any other class using curly braces, I get: `This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.ts(2497)`. I am not sure how to import `AMQPQueue` as well as some other classes. – Zenul_Abidin Jan 08 '22 at 04:58
  • You shouldn't have to import those classes manually? Or what are you trying to do? – Carl Hörberg Jan 08 '22 at 19:01
  • You get a AMQPQueue instance from AMQPClient::Channel#queue, you should never have to instanciate an AMQPQueue manually. – Carl Hörberg Jan 08 '22 at 19:05
  • 1
    It took me a couple days to adjust my API to the new module but it paid off, as I can see the messages being sent and received from the RabbitMQ management console. Thanks! – Zenul_Abidin Jan 12 '22 at 15:06