最近做了幾個(gè)項(xiàng)目,用js操作二進(jìn)制數(shù)據(jù),通過socket與后臺(tái)進(jìn)行傳輸。在此用博客做個(gè)記錄
首先是新建一個(gè)socket:
var socket=new WebSocket("ws://192.168.0.147");接著定義socket打開,連接之后執(zhí)行的函數(shù):
websocket有個(gè)屬性binaryType,可將其設(shè)置為“blob”或者“arraybuffer”,默認(rèn)格式為“blob”,做項(xiàng)目的時(shí)候忘記設(shè)置為“arraybuffer”了,結(jié)果在下面接收數(shù)據(jù)的時(shí)候就需要用Blob對(duì)象來接。
socket.onopen=function(){ //發(fā)送登錄幀,4-20位為手機(jī)號(hào) 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] }下面是轉(zhuǎn)成bype發(fā)送出去:
var loginBuffer=new ArrayBuffer(30);var loginDataview=new DataView(loginBuffer);//localstorageuserinfo為緩存在本地的用戶手機(jī)號(hào)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); //格式化時(shí)間同時(shí)按照年倆位月日時(shí)分秒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;}發(fā)送的流程大概就是這樣,先new ArrayBuffer對(duì)象,該對(duì)象需要填入緩沖區(qū)長度參數(shù),具體查看api==> https://msdn.microsoft.com/zh-cn/library/br212474(v=vs.94).aspx,
然后新建DataView對(duì)象,將ArrayBuffer傳進(jìn)去。然后用DataView的setUint和getUint方法按位進(jìn)行讀取設(shè)置,具體參考api==> https://msdn.microsoft.com/zh-cn/library/br212463(v=vs.94).aspx
下面是接收數(shù)據(jù)處理:
//接收消息onmessagesocket.onmessage=function(data){ var blob_=new Blob([data.data]); parseBlob(blob_); }//使用fileReader操作blob對(duì)象var reader = { readAs: function(type,blob,cb){ var r = new FileReader(); r.onloadend = function(){ if(typeof(cb) === 'function') { cb.call(r,r.result); } } try{ r['readAs'+type](blob); }catch(e){} }}function parseBlob(blob){ reader.readAs('ArrayBuffer',blob.slice(0,blob.size),function(arr){ var dataview_=new DataView(arr); //協(xié)議中第二位是判斷數(shù)據(jù)來源的 var socketConType=dataview_.getUint8(1); //轉(zhuǎn)成字符串讀取數(shù)據(jù) var modulelength=(dataview_.buffer.byteLength-46)/33; var modulestate={}; reader.readAs('Text',blob.slice(i*33+37,i*33+37+32),function(result){ modulestate[dataview_.getUint8(i*33+36)]=result; }); })}轉(zhuǎn)成字符串之后就可以為所欲為了。
以上就是我做項(xiàng)目時(shí)用到的操作二進(jìn)制數(shù)據(jù)的方法,按位讀取頭都要炸了······google開源的protobuf能夠設(shè)置完數(shù)據(jù)格式之后,所有讀取操作都不用自己拼接了,非常舒服。不過不懂后臺(tái)技術(shù),我只能跟在后臺(tái)大佬后面吃饃渣 TnT
這篇js操作二進(jìn)制數(shù)據(jù)方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持VeVb武林網(wǎng)。
新聞熱點(diǎn)
疑難解答