如何使用pm2正确配置现有nextjs项目中的socket.io

问题描述 投票:0回答:1

我为现有的 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

node.js next.js socket.io pm2
1个回答
0
投票
  1. 安装Redis 确保您的服务器上安装了 Redis。您可以按照Redis官网的说明进行安装。

  2. 更新您的 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');
  });
});
  1. 与 PM2 一起运行

使用 PM2 时,您需要确保应用程序的每个实例都使用相同的 Redis 适配器。您不需要手动设置worker; PM2 会为您处理。

通过 PM2 开始您的申请

pm2 start your-app.js -i 4 # Replace 4 with the number of instances you want

然后加载平衡器

希望我的解决方案对您有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.