我对在Node JS中分叉TCP客户端有疑问。这是场景。
到目前为止,这是我的方法。
// 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不会延迟,消息也不会循环。有什么解决办法吗?谢谢。
答案 0 :(得分:0)
如果您希望两个叉子相距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是流协议,而不是基于消息的协议。因此,要描述消息之间的差异,您必须在阅读时解析流。您不应该依赖与发送时完全相同的数据块中到达的数据。可以将其分解为较小的块,也可以将多个单独写入的块组合到同一到达的数据包中。例如,在这种情况下,您可以在每个消息的末尾放置一个\ n,并在读取TCP流时将其用作消息定界符,这样就可以将每个传入的消息分别解析,即使它们是由TCP组合成的。同一包。
或者您可以在TCP之上使用基于消息的协议(例如webSocket),该协议会为您打包和解压缩成不同的消息,并且只会向您传递完成的消息和单独的消息。