NodeJS 从函数更新后套接字未触发

xtfmy6hx  于 2023-08-04  发布在  Node.js
关注(0)|答案(1)|浏览(91)

我正在尝试构建一个小应用程序,它从gist.github随机获取一个文件,并将gist转换为图像(我没有编写这部分,它按预期工作)。
一旦文件被写入svg,我就调用socket方法向客户端发出一条消息。在收到消息时,客户端应该获取图像的新版本,并将其设置为html中的src属性。
以下是我的服务器js代码的截断版本:

const PORT = 8080;
const SOCKET_PORT = 3000;
let interval = 5000;
const io = new Server(SOCKET_PORT);

const getRandomGists = () => {
  // some vars here
  fetch(rndGist)
    .then((res) => res.text())
    .then((body) => {
      const { window } = new JSDOM(body);
      const { document } = window;
      const codeBlock = document.querySelectorAll(".blob-code-inner");
      console.log(`rndGist: ${rndGist}. Time: ${now}`);
      return codeBlock;
    })
    .then((codeBlock) => {
      const fauxCode = new FauxCode(codeBlock, options);
      fs.writeFileSync(filename, fauxCode.render());
    })
    .then(() => {
      io.on("connection", (socket) => {
        socket.emit("imageUpdate", "Image updated"); // this only seems to work when hitting refresh in the browser
        socket.on("customMessage", (arg) => {
          console.log(arg);
        });
        console.log("Server should be emiting message");
      });
    });
};

getRandomGists();

setInterval(() => {
  getRandomGists();
}, interval);

app.use(express.static("public"));

app.listen(PORT, () => console.log(`Server listening on: ${PORT}`));

字符串
在我的客户端中,我使用了以下js:

const socket = io("ws://localhost:3000");

socket.on("imageUpdate", (arg) => {
  reloadImg("../img/fauxcode.svg");
  console.log(arg, `reloadImg from client`);
});

function reloadImg(url) {
  const now = new Date().getTime();
  fetch(url, { cache: "reload", mode: "no-cors" });
  const wrapper = document.querySelector(".code");
  wrapper.setAttribute(`src`, `${url}?timestamp=${now}`); // I tried adding this in order to generate a unique parameter on the filename
  socket.emit("customMessage", "Emiting from the client!");
}


html文件看起来像这样:

<head>
    <script src="https://cdn.socket.io/socket.io-3.0.1.min.js"></script>
  </head>
  <body>
    <img src="./img/fauxcode.svg" class="code" alt="Alt text" />
    <script type="module" src="js/client.js"></script>


以下是硬刷新后的一些控制台日志记录:

rndGist: https://gist.github.com/pengzhile/448bfcfd548b3ae4e665a84cc86c4694. Time: 8:32:23
rndGist: https://gist.github.com/drewolson/4771479. Time: 8:32:30
Server should be emiting message
Server should be emiting message
Server should be emiting message
Emiting from the client!
Emiting from the client!
Emiting from the client!
Emiting from the client!
Emiting from the client!
Emiting from the client!
Emiting from the client!
Emiting from the client!
Emiting from the client!
rndGist: https://gist.github.com/omz/05f096319c23c4addba9. Time: 8:32:36
rndGist: https://gist.github.com/pkuczynski/8665367. Time: 8:32:42


我意识到我的服务器代码每次调用函数时都会打开一个新的连接,我假设这不是理想的,或者我应该在打开另一个连接之前关闭这个连接?或者我想知道我是否在rndGist函数外部打开连接,但是在函数完成后,我如何访问套接字参数来发出消息?
我已经尽量使所有的代码示例简洁,如果你需要看到更多的只是让我知道。
我希望有人能看到一个明显的解决办法。TIA

7rtdyuoh

7rtdyuoh1#

我可以想象你想要不止一个客户端,所以,我相信这也解决了这个问题。

const PORT = 8080;
const SOCKET_PORT = 3000;
const interval = 5000;
const io = new Server(SOCKET_PORT);

// an array of client sockets
let clients = [];
io.on("connection", (socket) => {
    clients.push(socket);
    socket.on("customMessage", (arg) => {
        console.log(arg);
    });
});
const getRandomGists = () => {
    fetch(rndGist)
    .then(res => res.text())
    .then(body => {
        const { window } = new JSDOM(body);
        const { document } = window;
        const codeBlock = document.querySelectorAll(".blob-code-inner");
        console.log(`rndGist: ${rndGist}. Time: ${now}`);
        const fauxCode = new FauxCode(codeBlock, options);
        fs.writeFileSync(filename, fauxCode.render());
        clients.forEach((socket, i) => {
            try {
                socket.emit("imageUpdate", "Image updated");
            } catch {
                // remove socket if there was an error?
                // This may be a naive way to do this though
                clients[i] = null;
            }
        });
        // remove "errored" clients
        clients = clients.filter(socket => socket);
    });
};

getRandomGists();

setInterval(getRandomGists, interval);

app.use(express.static("public"));

app.listen(PORT, () => console.log(`Server listening on: ${PORT}`));

字符串

相关问题