节点 JS 分叉 TCP 客户端
Node JS Fork TCP Client
我对在 Node JS 中分叉 TCP 客户端有疑问。这是场景。
- 客户端将连接到服务器(建立?)。
- 客户端将第一条消息写入服务器。
- 客户端将第二条消息写入服务器。
- 'write' 方法将无限循环,延迟 5 秒。
- 点号 1-4 将被分叉并创建一个新的 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 }
当我 运行 代码时,叉子不会延迟,消息也不会循环。有什么解决办法吗?谢谢。
如果您希望两个叉子相隔 8 秒,则 setTimeout()
需要不同的时间。 setTimeout()
没有阻塞,所以你所有的代码都在安排两个 setTimeout()
s - 从现在开始每个 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,它会为您打包和解包成不同的消息,并且只会向您传送完成的单独消息。
我对在 Node JS 中分叉 TCP 客户端有疑问。这是场景。
- 客户端将连接到服务器(建立?)。
- 客户端将第一条消息写入服务器。
- 客户端将第二条消息写入服务器。
- 'write' 方法将无限循环,延迟 5 秒。
- 点号 1-4 将被分叉并创建一个新的 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 }
当我 运行 代码时,叉子不会延迟,消息也不会循环。有什么解决办法吗?谢谢。
如果您希望两个叉子相隔 8 秒,则 setTimeout()
需要不同的时间。 setTimeout()
没有阻塞,所以你所有的代码都在安排两个 setTimeout()
s - 从现在开始每个 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,它会为您打包和解包成不同的消息,并且只会向您传送完成的单独消息。