我为现有的 next js 应用程序创建了一个视频聊天并且它可以工作,但是是时候将其安装到现有应用程序上了,然后 pm2 和我当前的实现自然失败了:
const nextApp = next({ dev: config.dev });
nextApp.prepare()
.then(() => {
const app: Express = express();
const server: http.Server = http.createServer(app);
const io: socketio.Server = new socketio.Server();
io.attach(server);
io.on('connection', (socket: socketio.Socket) => {
console.log('Socket connected!!!');
socket.on(SOCKET_ACTIONS.JOIN_ROOM, data => {
let { room: roomID } = data;
const { rooms: joinedRooms } = socket;
if (Array.from(joinedRooms).includes(roomID)) {
return console.warn('Already connected');
}
const clients = Array.from(io.sockets.adapter.rooms.get(roomID) || []);
console.log('socket clients: ', clients); // can return empty array becouse another pm2 process
clients.forEach(clientID => {
// exists users add new user peer to self peers
io.to(clientID).emit(SOCKET_ACTIONS.ADD_PEER, {
peerID: socket.id,
createOffer: false
}
// new user send offer for connection
socket.emit(SOCKET_ACTIONS.ADD_PEER, {
peerID: clientID,
createOffer: true
});
}
socket.join(roomID); // connect to room
}
// another socket actions
}
app.use.....
请告诉我,如何正确配置它以使其正常工作,同时考虑到用户可以在不同的工作人员上?
在这种情况下是否有必要使用redis?它会破坏我的代码吗?我的意思是这个地方例如: const 客户端 = Array.from(io.sockets.adapter.rooms.get(roomID) || []);
如果我必须使用 redis 那么如果我理解正确的话我应该有这样的东西:
const app: Express = express();
const server: http.Server = http.createServer(app);
const sockets = require('socket.io');
const redis = require('socket.io-redis');
const bindListeners = (io) => {
io.on('connection', socket => {
// previous code
});
}
const io = sockets(server, {
transports: ['websocket']
});
io.adapter(redis({host: 'localhost', port: 6379})); // i want to use [email protected]
bindListeners(io);
nextApp.prepare().then(() => {...next app all logic...});
在这种情况下,平衡器应该将套接字的流量发送到哪里? (这里我什么都不懂,另一个人在做这个,但我必须告诉他这个信息)? 感谢您的帮助。
我尝试使用https://socket.io/docs/v4/pm2/
const nextApp = next({ dev: config.dev });
const app: Express = express();
const server: http.Server = http.createServer(app);
const io = require('socket.io')(server, {});
io.adapter(createAdapter());
setupWorker(io);
io.on('connection', socket => socketServer(socket, io));
//套接字服务器
export default (socket, io) => {
console.log('Socket connected, ID: ', socket.id);
// same code as above
事实证明我为 4 个 pm2 进程创建了 4 个 IO 实例, 我无法得到:io.sockets.adapter.rooms.get(roomID),我也认为它不会工作:socket.broadcast.emit
安装Redis 确保您的服务器上安装了 Redis。您可以按照Redis官网的说明进行安装。
更新您的 Socket.IO 配置
const express = require('express'); const http = require('http'); const next = require('下一个');
块引用
const socketio = require('socket.io');
const redisAdapter = require('socket.io-redis');
const nextApp = next({ dev: config.dev });
const app = express();
const server = http.createServer(app);
const io = socketio(server);
// Use Redis as the adapter
io.adapter(redisAdapter({ host: 'localhost', port: 6379 }));
// Your socket.io logic here
io.on('connection', (socket) => {
// Previous code
});
nextApp.prepare().then(() => {
// Your Next.js logic here
app.get('/', (req, res) => {
// Handle your routes
});
server.listen(3000, (err) => {
if (err) throw err;
console.log('> Ready on http://localhost:3000');
});
});
使用 PM2 时,您需要确保应用程序的每个实例都使用相同的 Redis 适配器。您不需要手动设置worker; PM2 会为您处理。
通过 PM2 开始您的申请
pm2 start your-app.js -i 4 # Replace 4 with the number of instances you want
然后加载平衡器
希望我的解决方案对您有所帮助。