在由于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