webrtc实现文件点对点上传

文件传输功能传统的web实现方案是利用服务器中转进行传输,效率并不是很高,但是把服务器这一环节取消掉,直接让客户端建立连接即可取消中转的这个操作来提高效率。web点对点连接使用的技术是webrtc这一技术,关于webrtc实现暂时不进行探索。首先实现一个基础的webrtc 的文件传输功能。

实现步骤

1.首先引入第三方库,使用peerjs库来简化webrtc的操作,peerjs内置了BinaryPack 库,方便我们以二进制的方式传输数据。
//首先引入peerjs库,这里使用1.4.7版本,1.5.0 blob转arrayBuffer有bug
<script src="https://unpkg.com/peerjs@1.4.7/dist/peerjs.min.js"></script>
2.完成基础的html布局以及初始化peer
初始化页面
	<div>	
		<input id="text" type="text">
    	<button id="content">连接</button>
    	我的id : <span id="pid"></span>
	<div>
    <div>
        <input id="msg" type="file">
        <button id="send">发送</button>
    </div>
初始化peer
var peer = new Peer();
//peer.on('open',event)会在创建peer对象后执行
peer.on('open', function(id) {
		//把id给到界面上便于使用
		//其他客户端可以调用peer.connect(id)建立连接
        document.getElementById("pid").innerHTML = id
});
//点击之后建立与输入id的连接
btn.onclick = () => {
        // peer.connect()
        let conn = peer.connect(document.getElementById('text').value)
		//initConn为统一的peer初始化方法 具体实现在下方
        initConn(conn)
}
//同时建立接收连接
    peer.on('connection', function(conn) {
        initConn(conn)
});

3.需要初始化连接后的方法,因此我们添加initConn函数
代码实现
    function initConn(conn) {
        conn.on('open', function() {
            // on('data',event)为接收数据后的操作
            conn.on('data', function(data) {
            });
            // 给第二个button添加点击事件 里面实现发送的操作
            document.getElementById('send').onclick = () => {
				//通过获取input的files获取对象,files为数组
                const file = document.getElementById('msg').files[0]
            }
        });

    }
4.获取文件后,需要将文件转换成arrayBuffer对象方便传输
实现File转arrayBuffer的方法,用到了FileReader对象
function fileToArrayBuffen(file) {
        // 创建 FileReader 对象
        let reader = new FileReader();
        return new Promise(resolve => {
            // FileReader 添加 load 事件
            reader.readAsArrayBuffer(file);
            reader.addEventListener('loadend', (event) => {
                var value= event.target.result;
                console.log(value)
                resolve(value)
                // event.target.result 中的保存的就是读取到的数据
            });
        })
    }
5.发送数据
在发送按钮的点击事件中添加以下代码
document.getElementById('send').onclick = () => {
                const file = document.getElementById('msg').files[0]
				//fileToArrayBuffer传入文件
                fileToArrayBuffer(document.getElementById('msg').files[0]).then((res) => {
					//使用send发送数据,传输文件名称,文件大小,文件类型,以及文件数据
                    conn.send({
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        file: res
           })
	})
}
6.接收数据
使用coon.on()监听收到的数据,并且根据需要转换成文件对象并保存。
conn.on('data', function(data) {
				//如果有file
                if (data.file) {
                    saveFileWithReader(new File([data.file], data.name),data.name,data.type)
                }
});

saveFileWithReader方法传入文件二进制文件,文件名,文件类型,该方法把arrayBuffer转换成Blob对象在保存到本地

function saveFileWithReader(fileData, filename, type) {
        var reader = new FileReader();
        reader.onload = function(event) {
            var blob = new Blob([fileData], { type: type });
            saveBlobToFile(blob, filename);
        };
        reader.readAsText(fileData);
 }
saveBlobToFile实现
function saveBlobToFile(blob, filename) {
        var a = document.createElement('a');
        a.href = window.URL.createObjectURL(blob);
        a.download = filename;
        a.click();
    }


至此完成了webrtc文件传输功能,现在传输速度还是不快,可以把文件分成多分进行传输提高传输效率,后续在进行更新