I'm trying to create a nats consumer class that can listen to a stream subject that contains a wildcard.
I was familiar with nats-streaming but since they decided to deprecate it for Jestream, I'm totally lost.
For example I have a publisher, which seems to work, that pushes messages to a Subject.Foo.Bar
stream.
I want my consumer to listen on Subject.*
and get all the nested messages.
import moment from 'moment';
import { consumerOpts, JetStreamPullSubscription, JsMsg, Msg, StringCodec } from 'nats';
import { IEvent } from '../events/event';
import { NatsClient } from './nats-client';
export abstract class NatsNestedListener<S extends IEvent>
{
abstract onMessage(data: S['data'], msg: JsMsg): Promise<void>;
abstract subject: S['subject'];
private client: NatsClient;
protected subscription: JetStreamPullSubscription;
constructor(client: NatsClient)
{
this.client = client;
}
private subscriptionOptions()
{
const options = consumerOpts();
options.ackWait(5000);
options.deliverAll();
options.startSequence(1);
options.durable(this.client.QueueGroupName);
options.manualAck();
return options;
}
async listen()
{
// Creates Stream if not exists
await this.client.initStream(`${this.subject}.*`);
this.subscription = await this.client.JetStreamClient.pullSubscribe(`${this.subject}.*`, { ...this.subscriptionOptions() });
this.subscription.pull({ batch: 0 });
for await(const jsMessage of this.subscription)
{
console.log('Message Received', `[Subject]: ${jsMessage.subject} - [Seq]: ${jsMessage.seq}`);
this.processMessage(jsMessage);
this.subscription.pull({ batch: 0 });
}
}
parseMessage(msg: JsMsg | Msg)
{
const stringCodec = StringCodec();
const decodedData = stringCodec.decode(msg.data)
return JSON.parse(decodedData);
}
async processMessage(msg: JsMsg)
{
const data = this.parseMessage(msg);
this.onMessage(data, msg);
}
}
I tried to pullSubscribe to Subject.*
Subject.>
but none of these solutions worked.