node.js - 将节点 TCP 流分成数据包的最佳实践?
问题描述
我正在使用 Node 的 TCP 客户端作为我的游戏的实时后端,它以固定长度的协议进行通信。例如,
0x00 - Connection Request
int32 Identifier
4 bytes long
0x01 - Position Update
int32 positionx
int32 positiony
8 bytes long
当然,Node 是这样工作的
socket.on("data", (data) => {
// Arbitary buffer of bytes
})
我只想在收到完整的数据包后一次处理一个数据包,但是最好的方法是A:继续添加到缓冲区直到收到完整的数据包,并且B:确保不包含 a 的数据第一个中的第二个数据包
解决方案
我就是这样解决的!
function readData(data, socket) {
console.log("Read chunk of data " + data.length + " bytes long")
while (data.length > 0) {
if (expectsNewPacket) {
packetBuffer = new Buffer(0)
currentPacketInfo = getPacketInformationFromHeader(data)
data = currentPacketInfo.slicedData
console.log("New packet: ident " + currentPacketInfo.ident + ", length: " + currentPacketInfo.length)
expectedLengthRemaining = currentPacketInfo.length
expectsNewPacket = false
}
// If the data is more than the rest of the packet, just concat the rest of the packet and remove it from our block
if (data.length >= expectedLengthRemaining) {
packetBuffer = Buffer.concat([packetBuffer, data.slice(0, expectedLengthRemaining)])
data = data.slice(expectedLengthRemaining)
processPacket(packetBuffer, socket)
expectsNewPacket = true
} else {
// Or if the data length is less than what we need, just add all that we can and we'll add more later
packetBuffer = Buffer.concat([packetBuffer, data.slice(0, data.length)])
data = data.slice(data.length)
}
}
}
推荐阅读
- javascript - 通过网络流式传输麦克风音频输入 (RAW PCM)
- localization - 为使用资源文件的不同人定制相同信封、相同语言但不同文本的 Docusign 通知?
- angular - 为使用 Service 渲染的 Angular Bootstrap 组件定义故事
- python - 使用 np.sqrt 处理后无法可视化图像
- angular - 如果标题跨越屏幕宽度,如何在量角器测试中验证 Angular Grid 的所有列标题?
- ios - 在使用 Blackberry Dynamics 时使用未声明的标识符 GDFileSystem
- powershell - Powershell在txt文件中输出记录列表
- javascript - 如何防止textarea重叠列表
- azure-devops - Azure devops 无法写入构建选项卡摘要页面
- javascript - Firebase Cloud Functions:如何更新多个函数使用的值