前端websocket使用心得-------二進制數據傳輸
在由於websocket是長連接,所以在一些業務場景下,前後臺的交互使用websocket通訊會比較合適,具體場景不贅述,比如說實時聊天等。
本文主要簡述一下前端如何使用websocket。
1、js有H5的window內置對象中有websocket方法,這個 通過new方法可以獲取到websocket通訊的客戶端。使用如下方法初始化一個websocket連接,獲取客戶端連接對象。
plugin = new wsSocket('ws://localhost:8000/server');
plugin = new wsSocket('wss://localhost:8000/server');
其中wss爲安全連接。這裏需要注意,在https的路徑下是不可以使用ws連接的(firefox及低版本chrome)。
2、此處列出幾個websocket的幾個監聽方法
onOpen :監聽連接成功
onerror:連接出錯
onClose:連接斷開
onMessage:收到消息
3、websocket發送消息使用send方法。
send支持的參數爲 字符串、Blob、ArrayBuffer等。
發送示例參考mdn。
開始進入正題,使用websocket發送文件。
1、從頁面input可以獲取到文件對象File。
2、使用FileReader讀取File內容,獲取到對應的ArrayBuffer對象。
3、爲了接收數據方便,我們需要給發送的數據增加一個頭部信息,用於標識每一次請求,以便後臺可以根據頭部信息來區分每次請求,並根據這個信息發送響應信息,前端可以在onmessge中解析這個頭部信息來跟請求對應上。
4、ArrayBuffer是一個不可讀寫的內存對象,如果要加頭,需要用到視圖對象。
5、視圖對象有很多種,具體採用哪種根據自己協議來定。下文會貼出示例代碼,關鍵方法是要把多個視圖對象拼接成一個視圖對象,獲取到新的ArrayBuffer對象。
/**
* 合併類型化數組。
* @param resultConstructor
* @param arrays
* @returns {*}
*/
function concatenate(resultConstructor,...arrays) {
let totalLength = 0;
for (let arr of arrays) {
totalLength += arr.length;
}
let result = new resultConstructor(totalLength);
let offset = 0;
for (let arr of arrays) {
result.set(arr, offset);
offset += arr.length;
}
return result;
}
function sendBinary(file, fn) {
if(!wsPlugin) return false;
fn = fn || noop;
var fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = function () {
//文件內容的ArrayBuffer對象。
var arrayBuffer = fileReader.result;
//獲取文件視圖,用於讀取文件內容。
var array = new Int8Array(arrayBuffer);
//通訊標識
var id = guid();
EvtObserver.subscribe(id,fn);
//自定義文件頭。
var arrayHead = new Int8Array(2+1+id.length);
arrayHead[0] = "i".charCodeAt(0);
arrayHead[1] = "d".charCodeAt(0);
arrayHead[2] = id.length;
var arrayID = id.split("");
for(let i=0;i<arrayID.length;i++){
arrayID[i] = id.charCodeAt(i);
}
arrayHead.set(arrayID,3);
wsPlugin.send(concatenate(Int8Array,arrayHead,array).buffer);
};
return true;
}