最近做了幾個項目,用js操作二進位數據,通過socket與後臺進行傳輸。在此用博客做個記錄 首先是新建一個socket: 接著定義socket打開,連接之後執行的函數: websocket有個屬性binaryType,可將其設置為“blob”或者“arraybuffer”,預設格式為“blob”,做 ...
最近做了幾個項目,用js操作二進位數據,通過socket與後臺進行傳輸。在此用博客做個記錄
首先是新建一個socket:
1 var socket=new WebSocket("ws://192.168.0.147");
接著定義socket打開,連接之後執行的函數:
websocket有個屬性binaryType,可將其設置為“blob”或者“arraybuffer”,預設格式為“blob”,做項目的時候忘記設置為“arraybuffer”了,結果在下麵接收數據的時候就需要用Blob對象來接。
socket.onopen=function(){ //發送登錄幀,4-20位為手機號 var loginArr=[0X02,0X02,0X00,0X1E,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0D,0X0A] }
下麵是轉成bype發送出去:
var loginBuffer=new ArrayBuffer(30); var loginDataview=new DataView(loginBuffer); //localstorageuserinfo為緩存在本地的用戶手機號 var telArr=localstorageuserinfo.TelPhone; var loginTime=tempTrans(); for(var i=0;i<loginArr.length;){ loginDataview.setInt8(i,loginArr[i]); if(i>3&&i<(telArr.length+4)){ loginDataview.setInt8(i,telArr.charCodeAt(i-4)); } if(i>19&&i<loginArr.length-2){ loginDataview.setInt8(i,loginTime[i-20]); } i++; } //登錄包 socket.send(loginDataview.buffer); //格式化時間同時按照年倆位月日時分秒1位由高到底排序 function tempTrans(time){ if(!time){ time=new Date(); } var u32Dataview=new DataView(new Uint16Array([time.getFullYear()]).buffer); var uint8=[]; uint8.push(new DataView(new Uint8Array([0X00]).buffer).getUint8(0)) for(var i=u32Dataview.byteLength-1;i>=0;i--){ uint8.push(u32Dataview.getUint8(i)) } uint8.push(new DataView(new Uint8Array([time.getMonth()+1]).buffer).getUint8(0)); uint8.push(new DataView(new Uint8Array([time.getDate()]).buffer).getUint8(0)); uint8.push(new DataView(new Uint8Array([time.getHours()]).buffer).getUint8(0)); uint8.push(new DataView(new Uint8Array([time.getMinutes()]).buffer).getUint8(0)); uint8.push(new DataView(new Uint8Array([time.getSeconds()]).buffer).getUint8(0)); return uint8; }
發送的流程大概就是這樣,先new ArrayBuffer對象,該對象需要填入緩衝區長度參數,具體查看api==> https://msdn.microsoft.com/zh-cn/library/br212474(v=vs.94).aspx,
然後新建DataView對象,將ArrayBuffer傳進去。然後用DataView的setUint和getUint方法按位進行讀取設置,具體參考api==> https://msdn.microsoft.com/zh-cn/library/br212463(v=vs.94).aspx
下麵是接收數據處理:
1 //接收消息onmessage 2 socket.onmessage=function(data){ 3 var blob_=new Blob([data.data]); 4 parseBlob(blob_); 5 } 6 //使用fileReader操作blob對象 7 var reader = { 8 readAs: function(type,blob,cb){ 9 var r = new FileReader(); 10 r.onloadend = function(){ 11 if(typeof(cb) === 'function') { 12 cb.call(r,r.result); 13 } 14 } 15 try{ 16 r['readAs'+type](blob); 17 }catch(e){} 18 } 19 } 20 function parseBlob(blob){ 21 reader.readAs('ArrayBuffer',blob.slice(0,blob.size),function(arr){ 22 var dataview_=new DataView(arr); 23 //協議中第二位是判斷數據來源的 24 var socketConType=dataview_.getUint8(1); 25 //轉成字元串讀取數據 26 var modulelength=(dataview_.buffer.byteLength-46)/33; 27 var modulestate={}; 28 reader.readAs('Text',blob.slice(i*33+37,i*33+37+32),function(result){ 29 modulestate[dataview_.getUint8(i*33+36)]=result; 30 }); 31 }) 32 }
轉成字元串之後就可以為所欲為了。
以上就是我做項目時用到的操作二進位數據的方法,按位讀取頭都要炸了······google開源的protobuf能夠設置完數據格式之後,所有讀取操作都不用自己拼接了,非常舒服。不過不懂後臺技術,我只能跟在後臺大佬後面吃饃渣 TnT
第一次寫博客,希望各位能多指導交流