最近使用了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);
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。
新聞熱點
疑難解答