【问题标题】:Socket.io socket listener not updating in nextjs apiSocket.io 套接字侦听器未在 nextjs api 中更新
【发布时间】:2023-01-07 21:08:55
【问题描述】:

我有一个 Next.js 项目,它设置了最简单的 Socket.IO 实现。下面是代码。

//  pages/index.tsx

let socket: Socket;
const Home: NextPage = () => {
  useEffect(() => {
    async function socketInit() {
      //start server
      await fetch("http://localhost:3000/api/socket");

      // connects to the socket
      socket = io();
      socket.on("connect", () => {
        console.log("hello");
      });
    }

    socketInit();
  }, []);

  return (
    <button
      onClick={() => {
        socket.emit("test");
      }}
    >
      hello
    </button>
  );
};
//  pages/api/socket.ts

export default function handler(
  req: NextApiRequest,
  res: Res
) {
  if (res.socket.server.io) { res.end(); return; }

  const io = new IOServer(res.socket.server);
  res.socket.server.io = io;
  io.on('connection', socket => {
    socket.on('test', () => {
      console.log("1");  //Changing it to "2" doesn't do anything until dev is restarted.
    });
  });

  res.end();
}

出于某种原因,服务器中的listener 不会从热重载更新。重启开发是唯一的方法。这是为什么?

【问题讨论】:

    标签: node.js websocket next.js socket.io


    【解决方案1】:

    我认为这里有两个问题:

    1. 您实例化 IOServer 的响应对象不会在 HMR 后重新创建,它仍然引用打印 1 的回调函数,它在内存中某处徘徊。
    2. 要解决此问题,您需要主动调用处理程序方法,取消订阅旧的回调函数并重新订阅新的(替换的)回调函数。仅通过套接字进行交互是不够的。不幸的是,我看到的所有教程都将处理程序称为socket,这是一种误导。它应该被称为setup-socket-handler。它所做的是从这个处理程序的响应对象中检索实际的服务器,并向底层服务器注册一个IOSocket服务器,然后它将注册一个新的处理程序/端点/socket.io,用于客户端和服务器之间的通信.

      这是我想出的。这不应该按原样在生产中使用(确保替换在生产中只发生一次,就像在原来的那样):

      const SocketHandler = (
        req: NextApiRequest,
        res: NextApiResponseWithSocket
      ): void => {
        if (res.socket.server.io != null) {
          logger.info("Socket is already running");
          res.socket.server.io.removeAllListeners("connection");
          res.socket.server.io.on("connection", onConnection);
        } else {
          logger.info("Socket is initializing");
          const io = new Server<ClientToServerEvents, ServerToClientEvents>(
            res.socket.server
          );
          io.engine.on("connection_error", (err: unknown) => {
            logger.error(`Connection error: ${err}`);
          });
          res.socket.server.io = io;
      
          io.on("connection", onConnection);
        }
        res.end();
      };
      

      在更改回调函数和 nextjs 执行其 HMR 后,需要按 2 中所述调用处理程序一次。我通过重新加载我的前端页面来执行此操作,该页面向套接字处理程序发送请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 2018-04-06
      • 2021-08-17
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      相关资源
      最近更新 更多