I have search everywhere and i cant find a good solution to my problem (witch i think is more..generic..i want to learn how and why). Im using google pubsub and i have a service in my project. It has two functions. I have require the file in app.js and listen. But how can i listen elsewhere in the app? Like say in a controller? Here is the messageService.ts code:
require('dotenv').config();
const {PubSub} = require('@google-cloud/pubsub');
let messageCount = 0;
let projectId = 'xxx';
let topicName = 'xxxt';
let subscriptionName = 'xxx';
// Instantiates a client
const pubsub = new PubSub({projectId});
// Creates a new topic
const topic = pubsub.topic(topicName);
const subscription = topic.subscription(subscriptionName);
module.exports = {
listenForMessages : () => {
const messageHandler = message => {
console.log(`Received message ${message.id}:`);
console.log(`\tAgresso Data: ${message.data}`);
//console.log(`\tAttributes: ${message.attributes}`);
messageCount += 1;
message.ack();
};
subscription.on('message', messageHandler);
},
sendTestMessage : () => {
let messageObject = {
action: 'insert',
objectType: 'resource',
objectId: 12456,
stamp: Date.now()
}
topic.publish(Buffer.from(JSON.stringify(messageObject)));
console.log('sent test message') ;
}
}
Your subscription
constant isn't bound to be used only in this file.
I suggest you to have a different approach/architecture. One where you have a file named PubSubConnection.ts
where you do your whole PubSub/topic/subscription instantiation and share it across your whole project. This way you won't have to re-create a new topic each time you want to use it. Maybe even factorized as you can you sub to any topic.
Example:
app.ts
import dotenv from 'dotenv';
dotenv.config();
import { PubSub } from '@google-cloud/pubsub';
import express from 'express';
import PubSubConnection from "./PubSubConnection";
import { sendTestMessage } from './listenSub';
const app = express();
// DI (dependency injection)
// Create a one time pubsub as you will certainly only use the same project_id across your app
const pubSub = new PubSub({ projectId: process.env.PROJECT_ID });
// Create the connection to the topic/subscription dynamically here or anywhere else
// in your di where your service/component need an access to a special topic/subscription
const pubSubConnection = new PubSubConnection(pubSub, 'your_topic_name', 'your_sub_name');
// this members could be passed to any services that your app runs
const topic = pubSubConnection.getTopic;
const subscription = pubSubConnection.getSubscription;
// And use as many function anywhere you need it
// by just passing it the already created topic/subscription
sendTestMessage(topic);
app.listen(process.env.PORT, () => {
console.log('Server started');
});
PubSubConnection.ts
// Dotenv should always be loaded first in your application (aka app.js in your case) and in the 1st line
// because it only need to be loaded 1 time for the env variable to be accessible
// there is no neeed to load it everywhere you need to access env var
// require('dotenv').config();
import { PubSub, Subscription, Topic } from '@google-cloud/pubsub';
export default class TopicSubConnection {
topic: Topic
subscription: Subscription
constructor(
private readonly pubSub: PubSub,
private readonly topicName: string,
private readonly subscriptionName: string
) {
this.topic = new Topic(this.pubSub, this.topicName);
this.subscription = new Subscription(this.pubSub, this.subscriptionName);
}
public get getTopic(): Topic {
return this.topic;
}
public get getSubscription(): Subscription {
return this.subscription;
}
}
subOperations.ts
import { Subscription, Topic, Message } from "@google-cloud/pubsub";
let messageCount = 0;
export const listenForMessages = (subscription: Subscription): void => {
const messageHandler = (message: Message) => {
console.log(`Received message ${message.id}:`);
console.log(`\tAgresso Data: ${message.data}`);
//console.log(`\tAttributes: ${message.attributes}`);
messageCount += 1;
message.ack();
};
// the handler could be an array of functions, this means you could have different
// functions listening to the same subscription
subscription.on('message', messageHandler);
};
export const sendTestMessage = (topic: Topic): void => {
let messageObject = {
action: 'insert',
objectType: 'resource',
objectId: 12456,
stamp: Date.now()
}
topic.publish(Buffer.from(JSON.stringify(messageObject)));
console.log('sent test message')
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.