如何在 NodeJS Express 应用程序的其他地方使用连接
How to use a connection elsewhere in NodeJS Express app
我到处搜索,但找不到解决我问题的好方法( 我认为更..通用..我想了解如何以及为什么)。
我正在使用 google pubsub,我的项目中有一项服务。它有两个功能。我需要 app.js 中的文件并收听。但是我怎样才能在应用程序的其他地方收听呢?就像在控制器中说的那样?这是 messageService.ts 代码:
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') ;
}
}
您的 subscription
常量未必只能在此文件中使用。
我建议你换一个 approach/architecture。一个是你有一个名为 PubSubConnection.ts
的文件,你可以在其中进行整个 PubSub/topic/subscription 实例化并在整个项目中共享它。这样您就不必在每次要使用新主题时都重新创建它。甚至可以分解为任何主题。
示例:
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')
};
我到处搜索,但找不到解决我问题的好方法( 我认为更..通用..我想了解如何以及为什么)。 我正在使用 google pubsub,我的项目中有一项服务。它有两个功能。我需要 app.js 中的文件并收听。但是我怎样才能在应用程序的其他地方收听呢?就像在控制器中说的那样?这是 messageService.ts 代码:
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') ;
}
}
您的 subscription
常量未必只能在此文件中使用。
我建议你换一个 approach/architecture。一个是你有一个名为 PubSubConnection.ts
的文件,你可以在其中进行整个 PubSub/topic/subscription 实例化并在整个项目中共享它。这样您就不必在每次要使用新主题时都重新创建它。甚至可以分解为任何主题。
示例:
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')
};