javascript - Node JS Fork TCP 客户端

标签 javascript node.js networking tcp fork

我有关于在 Node JS 中 fork TCP 客户端的问题。这是场景。

  1. 客户端将连接到服务器(建立?)。
  2. 客户端会将第一条消息写入服务器。
  3. 客户端将第二条消息写入服务器。
  4. “write”方法将无限循环,延迟 5 秒。
  5. 点 1-4 将被 fork 并创建一个新的 TCP 连接(不使用与之前相同的连接),延迟 8 秒。

这是我迄今为止的做法。

// tcp_client.js

const cluster = require('cluster')

if (cluster.isMaster) {
  for (let i = 0; i < 2; i += 1) {
    setTimeout(() => {
      cluster.fork()
    }, 8000) // I expect this will delay between one and another fork
  }
} else {
  console.log(`Connected on ${process.pid}`)
  require('./sender').send()
}
cluster.on('exit', (worker) => {
  console.log('server',`Worker %d died :( ${worker.id}`);
  cluster.fork();
})
// sender.js

const net = require('net')
const send = () => {
  const client = new net.Socket()
  client.connect(8090, 'localhost', () => {
    const firstMessage = 'first_message'
    const secondMessage = 'second_message'
    const write = function () {
      client.write(firstMessage)
      /*
        The reason why I'm using setTimeout() is because if I write it as
        `client.write(firstMessage)
        client.write(secondMessage)`
        The second message won't be sent. Is there any better methods?
      */
      setTimeout(() => {
          client.write(secondMessage)
      }, 1);
    }

    setTimeout(write, 5000) // I expect this will loop infinitely
  })
}

module.exports = { send }

当我运行代码时, fork 不会延迟,消息也不会循环。有什么解决办法吗?谢谢。

最佳答案

如果您希望两个 fork 相隔 8 秒,则需要在 setTimeout() 上改变时间。 setTimeout() 不会阻塞,因此您的所有代码所做的就是安排两个 setTimeout() - 从现在开始每个 8 秒。这将安排一个为 8 秒,另一个为 16 秒:

// tcp_client.js

const cluster = require('cluster')

if (cluster.isMaster) {
  for (let i = 0; i < 2; i += 1) {
    setTimeout(() => {
      cluster.fork()
    }, (i + 1) * 8000);
  }
} else {
  console.log(`Connected on ${process.pid}`)
  require('./sender').send()
}
cluster.on('exit', (worker) => {
  console.log('server',`Worker %d died :( ${worker.id}`);
  cluster.fork();
})

而且,您的写入代码不会循环,因为 setTimeout(write, 5000) 位于 connect 事件处理程序内,而不是 write() 内 函数。因此,当 connect 事件触发时,它会被调用一次,并且不会再次被调用。如果您希望 write() 重复,请将其放入 write() 函数本身(或使用 setInterval())。

// sender.js

const net = require('net')
const send = () => {
  const client = new net.Socket()
  client.connect(8090, 'localhost', () => {
    const firstMessage = 'first_message'
    const secondMessage = 'second_message'
    const write = function () {
      client.write(firstMessage)

      setTimeout(() => {
          client.write(secondMessage)
      }, 1);

      setTimeout(write, 5000) // I expect this will loop infinitely
    }
    write();

  })
}

module.exports = { send }

此外,连续执行两次这样的 client.write() 调用也是完全可以的 - 两者都会被发送。但是,TCP 可能会将它们合并到同一个数据包中。 TCP 是一种流协议(protocol),而不是基于消息的协议(protocol)。因此,为了描述消息之间的差异,您必须在读取时解析流。您不应该依赖于以与发送时完全相同的数据 block 形式到达的数据。它可以被分解成更小的 block ,或者可以将多个单独写入的 block 组合成同一个到达的数据包。例如,在这种情况下,您可以在每个消息的末尾放置一个\n,并在读取 TCP 流时将其用作消息分隔符,这样您就可以单独解析每个传入消息,即使它们是由 TCP 组合到相同的数据包。

或者您可以在 TCP 之上使用基于消息的协议(protocol),例如 webSocket,它会为您打包和解包为不同的消息,并且仅向您传递完整且单独的消息。

关于javascript - Node JS Fork TCP 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59375346/

相关文章:

javascript - 我无法对数组中的数字进行排序(尝试了此处编写的所有内容,但仍然不起作用)

javascript - 在 D3.js 中设置标记结束箭头的颜色

javascript - skygear/react-chat-demo app.html 不起作用

c# - 到特定客户端的 TCP C# 数据包

java InetAddress.getLocalHost();返回 127.0.0.1 ...如何获得真实 IP?

javascript - 将对象转换为数组

node.js - 使用 Node.js 将文件从字符串上传到 Box API

javascript - 如何在嵌入中调用 .username 属性? (不和谐.js)

C++ 服务器,System.10014 错误,使用 Boost

javascript - 如何复制文件夹中的文件进行构建?