node.js - 将带有集群模块项目的node.js部署到heroku时绑定EADDRINUSE null错误
问题描述
我有一个在前端使用 Node 集群模块、Express.js、Socket.io 和 React 构建的 Messenger 应用程序。我一直在尝试将我的应用程序部署到 heroku,但是当我检查 heroku 控制台时出现 EADDRINUSE null 错误,并且我还看到该应用程序在 heroku 日志中以代码 H10 崩溃。我意识到工作线程可能正在连接到同一个端口,因此出现了错误。我尝试了许多不同的方法,但我无法解决问题。
这是我的 server.js 代码和集群模块代码:
require('dotenv').config();
const express = require('express'),
mongoose = require('mongoose'),
socketio = require('socket.io'),
helmet = require('helmet'),
hpp = require('hpp'),
path = require('path'),
net = require('net'),
cluster = require('cluster');
const num_processes = require('os').cpus().length;
const io_redis = require('socket.io-redis');
const farmhash = require('farmhash');
const port = process.env.PORT || 8080;
const User = require('./models/User');
const socketMain = require('./sockets/socketMain');
if (cluster.isMaster) {
let workers = [];
// Helper function for spawning worker at index 'i'.
let spawn = function(i) {
workers[i] = cluster.fork();
// Optional: Restart worker on exit
workers[i].on('exit', function(code, signal) {
// console.log('respawning worker', i);
spawn(i);
});
};
// Spawn workers.
for (var i = 0; i < num_processes; i++) {
spawn(i);
}
const worker_index = function(ip, len) {
return farmhash.fingerprint32(ip) % len; // Farmhash is the fastest and works with IPv6, too
};
const server = net.createServer({ pauseOnConnect: true }, (connection) =>{
let worker = workers[worker_index(connection.remoteAddress, num_processes)];
worker.send('sticky-session:connection', connection);
});
server.listen(port, process.env.IP, () => {
console.log(`Master listening on port ${port}`);
});
} else {
let app = express();
app.use(express.json({limit: '50mb'}));
app.use(helmet());
app.use(hpp());
// Mongo Connection
mongoose.connect(process.env.DB_URL, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false
})
.then(() => console.log('Connected to dB!'))
.catch(e => console.log(e));
// Don't expose our internal server to the outside world.
// Serve static assets if in production
if(process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static(path.join(__dirname, 'client', 'build')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'client', 'build', 'index.html'));
});
}
const server = app.listen(port, () => {
console.log("Worker listening...");
});
const io = socketio(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true
}
});
io.adapter(io_redis({ host: 'localhost', port: 6379 }));
io.on('connection', async (socket) => {
const userId = socket.handshake.query.userId;
//Socket code here
});
// Use API routes
const userRoutes = require('./routes/api/user'),
authRoutes = require('./routes/api/auth'),
messengerRoutes = require('./routes/api/messenger')(io);
app.use('/api/user', userRoutes);
app.use('/api/auth', authRoutes);
app.use('/messenger', messengerRoutes);
// Listen to messages sent from the master. Ignore everything else.
process.on('message', function(message, connection) {
if (message !== 'sticky-session:connection') {
return;
}
// Emulate a connection event on the server by emitting the
// event with the connection the master sent us.
server.emit('connection', connection);
connection.resume();
});
}
请帮我解决问题。
解决方案
推荐阅读
- python - 使用 API 从 Twitter 中提取数据
- python - 处理大型 if/else 的最佳方法
- javascript - 如何在javascript中通过id从对象数组中获取唯一数据
- css - 将 svg 图像旋转 90 度
- ruby-on-rails - 使用联接和分组依据的 Active Record 查询
- python - AWS Lambda 中的 Tweepy search_tweets
- c# - XmlTextReader 解析EntityName时出错c#
- typo3 - 安装 EXT:workspaces 后将内容移动到 Workspace
- python - 为什么 Firebase 存储下载小文件的速度很慢 - 本地
- python - 如何使用 pd.read_html 抓取具有 % 值的 HTML 表格?