最近使用了protobuf进行数据交互,发送在node.js接收前端的二进制数据出现了数据错误等问题。后来发现思路上面的问题,在req.on('data',()=>{})事件中的处理不适当才引发数据错乱。借此发
我先直接贴正确接收二进制数据代码
- const server = http.createServer((req, res) => {
- if(req.method==='OPTIONS'){
- res.setHeader("Access-Control-Allow-Origin", "*");
- res.statusCode=200;
- }
- if(req.method==='POST'){
- // 存储数组空间
- let msg=[];
- // 接收到数据消息
- req.on('data',(chunk)=>{
- if(chunk){
- msg.push(chunk);
- }
- })
- // 接收完毕
- req.on('end',()=>{
- // 对buffer数组阵列列表进行buffer合并返回一个Buffer
- let buf=Buffer.concat(msg);
- conosole.log(buf)//提取Buffer正确
- })
- }
- });
- server.listen(3000,'127.0.0.1');
在nodejs中接收buffer数据需要以数组阵列的方式存储然后通过buffer.concat对数组阵列合并创建新的arraybuffer。这样就正确的接收二进制数据了。
示例二:
以后端传送threejs中的点阵数组为例:
后端:
- let buffer = Buffer.alloc((points.length + 4) * 4)
-
- //points.length + 4:预留前四个数字为其他信息(比如两个数字为一组,或者三个数字为一组)
-
- //预留位置
- buffer.writeFloatLE(1, 0)
- buffer.writeFloatLE(2, 4)
- buffer.writeFloatLE(3, 8)
- buffer.writeFloatLE(4, 12)
-
- //buffer前四个数为信息
- //point数据从第16位开始写入
- for (let i = 0, len = points.length; i < len; i++) {
- buffer.writeFloatLE(points[i], i * 4 + 16)
- }
- res.send(buffer)
-
前端:
- let pointXhr = new XMLHttpRequest()
- pointXhr.onreadystatechange = function () {
- var DONE = pointXhr.DONE || 4;
- if (pointXhr.readyState === DONE) {
- let buffer = pointXhr.response
- let bufferArray = new Float32Array(buffer);
- for (var i = 0; i < buffer.length; ++i) {
- bufferArray[i] = buffer[i];
- }
- let pointsArray = bufferArray.slice(4)
- let points = []
- //pointsArray 点阵从第5个开始(前四个数为其他信息)
- for (let i = 0, l = pointsArray.length / 3; i < l; i++) {
- points.push({
- x: pointsArray[i * 3],
- y: pointsArray[i * 3 + 1],
- z: pointsArray[i * 3 + 2]
- })
- }
- callback(points)
- }
- }
- pointXhr.open("POST",url,true);
- pointXhr.responseType = 'arraybuffer';
- pointXhr.send(null);
前端接收图片buffer
- let imageXhr = new XMLHttpRequest()
- imageXhr.onreadystatechange = function () {
- var DONE = imageXhr.DONE || 4;
- if (imageXhr.readyState === DONE) {
- if (imageXhr.response) {
- let bufferArray = imageXhr.response
- let uint8Array = new Uint8Array(bufferArray);
- for (var i = 0; i < bufferArray.length; ++i) {
- uint8Array[i] = bufferArray[i];
- }
- callback(uint8Array)
- }
- }
- }
- imageXhr.open("POST",url,true);
- imageXhr.responseType = 'arraybuffer';
- imageXhr.send(null);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。