我有一个NodeJS文件index.js
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const router = express.Router();
const cron = require('node-cron');
const nodemailer = require('nodemailer');
const request = require('request');
const cheerio = require('cheerio');
const FCM = require('fcm-node');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
var admin = require('firebase-admin');
var serviceAccount = require('./serviceAccountKey.json');
var fcm = new FCM(serviceAccount);
var firebase = admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://ios-base-a2107.firebaseio.com'
});
const FETCH_DOMAIN = 'https://finance.yahoo.com/lookup/all?s=';
router.get('/', (req, res) => {
res.json({
msg: 'Something happening'
})
});
const checkPrice = () => {
var db = admin.database();
var ref = db.ref('alerts');
ref.on('value', (snapshot) => {
if (snapshot.val()) {
snapshot.forEach((child) => {
trackPrice(child);
})
}
}, (error) => {
console.log('The read failed: ' + error.code);
})
}
const sendEmailNotification = async (email, text, snapshot) => {
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'johndoe@gmail.com',
pass: '#######'
}
});
let mailOptions = {
from: 'johndoe@gmail.com',
to: 'sybunlongheng@gmail.com',
subject: text,
html: text
};
let info = await transporter.sendMail(mailOptions);
// update notify params
var db = admin.database();
var ref = db.ref('emails').child(snapshot.key);
const company = snapshot.val();
ref.update({
companyName: company.companyName,
price: company.price,
ticker: company.ticker,
notified: true
})
console.log('Message sent: %s', info.messageId);
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
}
const trackPrice = (child) => {
var snapshot = child.val();
const company = snapshot.companyName;
const price = snapshot.price;
const url = `${FETCH_DOMAIN}${snapshot.ticker}`;
request(url, (error, response, html) => {
if (!error && response.statusCode === 200) {
var $ = cheerio.load(html);
var stock_price = null;
$('table').find('tbody').find('tr').each(function(i, e) {
var column = $(this).prev();
if (column.children('td.data-col1').text() === snapshot.companyName) {
stock_price = column.children('td.data-col2').text();
}
});
if (stock_price != null) {
stock_price = parseFloat(stock_price.replace(/,/g, ''));
if (stock_price && Math.round(snapshot.price) == Math.round(stock_price)) {
// send email notification
admin.auth().listUsers()
.then((list) => {
list.users.forEach((user) => {
var customer = user.toJSON();
sendEmailNotification(customer.email, `The company ${snapshot.companyName}' stock price is reached to ${snapshot.price}`, child);
});
}).catch((error) => {
console.log('Error listing users:', error);
})
// Send push notification
var ref = firebase.database().ref('users');
ref.once('value')
.then(function(snapshot) {
var data = snapshot.val();
for (var i=0;i<data.length;i++) {
var fcmToken = data[i].fcmToken;
var collapseKey = 'new_message';
var message = {
to: fcmToken,
data: {
cpeMac: '000000000000',
type: 'malware',
},
notification: {
title: 'Stock Price',
body: `The company ${company}' stock price is reached to ${price}`,
tag: collapseKey,
icon: 'ic_notification',
color: '#18d821',
sound: 'default'
}
};
fcm.send(message, function(err, response) {
if (err) {
console.log(err);
} else {
console.log("Successfully sent with response: ", JSON.stringify(response));
}
})
}
})
}
}
}
})
}
const run_job = () => {
cron.schedule('0 * * * * *', () => {
checkPrice();
});
}
//run_job();
checkPrice();
app.use('/api', router);
app.listen(3000, () => {
console.log('\x1b[33m%s\x1b[0m', '** Express Development is listening on localhost:3000, open your browser on http://localhost:3000 **');
})
现在,我使用PM2启动它。
我不断得到
0|index | at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
0|index | at Function.Module._load (internal/modules/cjs/loader.js:552:3)
PM2 | App [index:0] exited with code [1] via signal [SIGINT]
PM2 | App [index:0] starting in -fork mode-
PM2 | App [index:0] online
0|index | Error: listen EADDRINUSE: address already in use :::3000
0|index | at Server.setupListenHandle [as _listen2] (net.js:1255:14)
0|index | at listenInCluster (net.js:1303:12)
0|index | at Server.listen (net.js:1391:7)
0|index | at Function.listen (/home/forge/john/public/ios-base-api/node_modules/express/lib/application.js:618:24)
0|index | at Object.<anonymous> (/home/forge/john/public/ios-base-api/index.js:153:5)
0|index | at Module._compile (internal/modules/cjs/loader.js:721:30)
0|index | at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
0|index | at Module.load (internal/modules/cjs/loader.js:620:32)
0|index | at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
0|index | at Function.Module._load (internal/modules/cjs/loader.js:552:3)
PM2 | App [index:0] exited with code [1] via signal [SIGINT]
PM2 | App [index:0] starting in -fork mode-
PM2 | App [index:0] online
0|index | Error: listen EADDRINUSE: address already in use :::3000
0|index | at Server.setupListenHandle [as _listen2] (net.js:1255:14)
0|index | at listenInCluster (net.js:1303:12)
0|index | at Server.listen (net.js:1391:7)
0|index | at Function.listen (/home/forge/john/public/ios-base-api/node_modules/express/lib/application.js:618:24)
0|index | at Object.<anonymous> (/home/forge/john/public/ios-base-api/index.js:153:5)
0|index | at Module._compile (internal/modules/cjs/loader.js:721:30)
0|index | at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
0|index | at Module.load (internal/modules/cjs/loader.js:620:32)
0|index | at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
0|index | at Function.Module._load (internal/modules/cjs/loader.js:552:3)
PM2 | App [index:0] exited with code [1] via signal [SIGINT]
PM2 | App [index:0] starting in -fork mode-
PM2 | App [index:0] online
0|index | Error: listen EADDRINUSE: address already in use :::3000
0|index | at Server.setupListenHandle [as _listen2] (net.js:1255:14)
0|index | at listenInCluster (net.js:1303:12)
0|index | at Server.listen (net.js:1391:7)
0|index | at Function.listen (/home/forge/john/public/ios-base-api/node_modules/express/lib/application.js:618:24)
0|index | at Object.<anonymous> (/home/forge/john/public/ios-base-api/index.js:153:5)
0|index | at Module._compile (internal/modules/cjs/loader.js:721:30)
0|index | at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
0|index | at Module.load (internal/modules/cjs/loader.js:620:32)
0|index | at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
0|index | at Function.Module._load (internal/modules/cjs/loader.js:552:3)
PM2 | App [index:0] exited with code [1] via signal [SIGINT]
PM2 | App [index:0] starting in -fork mode-
PM2 | App [index:0] online
EADDRINUSE:地址已在使用::: 3000
我的目标是在后台运行我的NodeJS应用,而不是每分钟启动一个新的。
有人可以告诉我我做错了什么吗?
目前我愿意接受任何建议。