mirror of
https://github.com/tl-open-source/tl-rtc-file.git
synced 2025-10-06 07:56:51 +08:00
851 lines
34 KiB
JavaScript
851 lines
34 KiB
JavaScript
// file.js
|
||
var file = null;
|
||
axios.get(window.prefix + "/api/comm/initData",{}).then((initData)=>{
|
||
let resData = initData.data;
|
||
file = new Vue({
|
||
el : '#fileApp',
|
||
data : function () {
|
||
let socket = null;
|
||
if (io){
|
||
socket = io(resData.wsHost);
|
||
}
|
||
return{
|
||
socket : socket,
|
||
config : resData.rtcConfig,
|
||
options : resData.options,
|
||
isJoined : false,
|
||
showReceiveFile : false,
|
||
showSendFile : false,
|
||
showLogs : false,
|
||
numSendFile: 150,
|
||
numReceiveFile : 150,
|
||
numLogs : 150,
|
||
currentMenu : 1,
|
||
logsHeight : 0,
|
||
|
||
nickName : "", //本人名称
|
||
socketId : 0, //本人的id
|
||
roomId : "10086", //房间号
|
||
fileReader : null, //文件读取对象
|
||
rtcConns : {}, //远程连接
|
||
remoteMap : {}, //远程连接map
|
||
|
||
chunkSize : 256 * 1024, //一块256kb
|
||
offset : 0, //当前文件分片位移
|
||
fileName : null, //文件名称
|
||
allSended : false,//当前文件是否全部发送给房间内所有用户
|
||
currentReceiveSize : 0, //统计收到文件的大小
|
||
currentSendingId : "", //当前正在发送的文件
|
||
chooseFile : null, //选择的文件
|
||
sendFileList : [], //发过文件的列表
|
||
receiveFileList : [], //接收文件的列表
|
||
logs : [], //记录日志
|
||
}
|
||
},
|
||
computed : {
|
||
createDisabled : function(){
|
||
return this.isJoined || this.fileName || !this.roomId;
|
||
},
|
||
exsitDisabled : function(){
|
||
return !this.isJoined;
|
||
},
|
||
uploadDisabled : function(){
|
||
return !this.fileName || this.allSended;
|
||
},
|
||
showSendFileList : function() {
|
||
return this.sendFileList && this.sendFileList.length > 5;
|
||
}
|
||
},
|
||
watch : {
|
||
currentMenu :function(newV,oldV){
|
||
|
||
},
|
||
allSended :function(newV,oldV){
|
||
|
||
},
|
||
fileName : function(newV,oldV){
|
||
this.chooseFile = this.$refs['self-file'].files[0];
|
||
if(!this.chooseFile) return;
|
||
if(!this.socketId) return;
|
||
|
||
this.$refs['sendProgress'].max = this.chooseFile.size;
|
||
|
||
this.socket.emit('message', {
|
||
emitType : "sendFileInfo",
|
||
name: this.chooseFile.name,
|
||
type: this.chooseFile.type,
|
||
size: this.chooseFile.size,
|
||
room : this.roomId,
|
||
from : this.socketId,
|
||
});
|
||
this.allSended = false;
|
||
|
||
let idList = [];
|
||
for(let id in this.remoteMap){
|
||
this.setRemoteInfo(id,{status : 0})
|
||
idList.push(id);
|
||
}
|
||
|
||
if(this.socketId){
|
||
let toIdStr = "";
|
||
if(idList.length > 0){
|
||
toIdStr += "发送给房间的 "+idList[0]+" ...等"+idList.length+"人";
|
||
}
|
||
for(let id in this.remoteMap){
|
||
this.sendFileList.push({
|
||
id : id,
|
||
name : this.chooseFile.name,
|
||
size : this.chooseFile.size,
|
||
type : this.chooseFile.type,
|
||
process : 0,
|
||
done : false,
|
||
toIdStr : toIdStr,
|
||
});
|
||
}
|
||
}
|
||
},
|
||
currentReceiveSize : function(newV,oldV){
|
||
this.currentReceiveSize = newV;
|
||
},
|
||
remoteMap : {
|
||
handler : function(newV,oldV){},
|
||
deep : true,
|
||
immediate : true
|
||
},
|
||
receiveFileList : {
|
||
handler : function (newV, oldV) {},
|
||
deep : true,
|
||
immediate : true
|
||
},
|
||
sendFileList : {
|
||
handler : function (newV, oldV) {},
|
||
deep : true,
|
||
immediate : true
|
||
}
|
||
},
|
||
methods : {
|
||
genNickName : function () {
|
||
// 获取指定范围内的随机数
|
||
function randomAccess(min,max){
|
||
return Math.floor(Math.random() * (min - max) + max)
|
||
}
|
||
|
||
// 解码
|
||
function decodeUnicode(str) {
|
||
//Unicode显示方式是\u4e00
|
||
str = "\\u"+str;
|
||
str = str.replace(/\\/g, "%");
|
||
//转换中文
|
||
str = unescape(str);
|
||
//将其他受影响的转换回原来
|
||
str = str.replace(/%/g, "\\");
|
||
return str;
|
||
}
|
||
|
||
function getRandomName(len){
|
||
let name = ""
|
||
for(let i = 0;i < len; i++){
|
||
let unicodeNum = ""
|
||
unicodeNum = randomAccess(0x4e00,0x9fa5).toString(16)
|
||
name += decodeUnicode(unicodeNum)
|
||
}
|
||
return name;
|
||
}
|
||
return getRandomName(4);
|
||
},
|
||
addPopup : function(msg) {
|
||
window.Bus.$emit("addPopup",msg);
|
||
},
|
||
cleanPopup : function(){
|
||
window.Bus.$emit("popupMap");
|
||
},
|
||
clickChooseFile : function(){
|
||
this.$refs['self-file'].click();
|
||
},
|
||
clickHome : function(show = true){
|
||
this.currentMenu = 1;
|
||
|
||
let body = document.body;
|
||
let menuBorder = document.querySelector(".menu__border");
|
||
let active = this.$refs['btnHome'];
|
||
let box = active.getBoundingClientRect();
|
||
|
||
body.style.backgroundColor = active.style.getPropertyValue("--bgColorBody");
|
||
offsetMenuBorder (box, menuBorder);
|
||
|
||
function offsetMenuBorder(box, menuBorder) {
|
||
let left = Math.floor(box.left - menuBorder.closest("menu").offsetLeft - (menuBorder.offsetWidth - box.width) / 2) + "px";
|
||
menuBorder.style.transform = `translate3d(${left}, 0 , 0)`
|
||
}
|
||
|
||
if(show){
|
||
this.clickSendFile();
|
||
}
|
||
},
|
||
clickRoom : function(show = true){
|
||
this.currentMenu = 2;
|
||
|
||
let body = document.body;
|
||
let menuBorder = document.querySelector(".menu__border");
|
||
let active = this.$refs['btnRoom'];
|
||
let box = active.getBoundingClientRect();
|
||
|
||
body.style.backgroundColor = active.style.getPropertyValue("--bgColorBody");
|
||
offsetMenuBorder (box, menuBorder);
|
||
|
||
function offsetMenuBorder(box, menuBorder) {
|
||
let left = Math.floor(box.left - menuBorder.closest("menu").offsetLeft - (menuBorder.offsetWidth - box.width) / 2) + "px";
|
||
menuBorder.style.transform = `translate3d(${left}, 0 , 0)`
|
||
}
|
||
|
||
if(show){
|
||
this.clickReceiveFile()
|
||
}
|
||
},
|
||
clickFile : function(show = true){
|
||
this.currentMenu = 3;
|
||
|
||
let body = document.body;
|
||
let menuBorder = document.querySelector(".menu__border");
|
||
let active = this.$refs['btnFile'];
|
||
let box = active.getBoundingClientRect();
|
||
|
||
body.style.backgroundColor = active.style.getPropertyValue("--bgColorBody");
|
||
offsetMenuBorder (box, menuBorder);
|
||
|
||
function offsetMenuBorder(box, menuBorder) {
|
||
let left = Math.floor(box.left - menuBorder.closest("menu").offsetLeft - (menuBorder.offsetWidth - box.width) / 2) + "px";
|
||
menuBorder.style.transform = `translate3d(${left}, 0 , 0)`
|
||
}
|
||
|
||
if(show){
|
||
this.clickReceiveFile()
|
||
}
|
||
},
|
||
//文件大小
|
||
getFileSizeStr : function (size){
|
||
let sizeStr = (size/1048576).toString();
|
||
let head = sizeStr.split(".")[0];
|
||
let tail = "";
|
||
if(sizeStr.split(".")[1]){
|
||
tail = sizeStr.split(".")[1].substr(0,3);
|
||
}
|
||
return head + '.' + tail + "M";
|
||
},
|
||
//点击下载文件
|
||
clickReceiveFile : function(){
|
||
this.showReceiveFile = !this.showReceiveFile;
|
||
if(this.showReceiveFile){
|
||
this.numReceiveFile = 50;
|
||
}else{
|
||
this.numReceiveFile = 150;
|
||
}
|
||
},
|
||
//点击发送文件
|
||
clickSendFile : function(){
|
||
this.showSendFile = !this.showSendFile;
|
||
if(this.showSendFile){
|
||
this.numSendFile = 50;
|
||
}else{
|
||
this.numSendFile = 150;
|
||
}
|
||
},
|
||
//点击查看日志
|
||
clickLogs : function(){
|
||
this.showLogs = !this.showLogs;
|
||
if(this.showLogs){
|
||
this.numLogs = 50;
|
||
}else{
|
||
this.numLogs = 150;
|
||
}
|
||
},
|
||
//创建房间
|
||
createRoom : function () {
|
||
if(this.fileName != null){
|
||
alert("请先加入房间再选文件")
|
||
return;
|
||
}
|
||
if (this.roomId) {
|
||
if(this.roomId.toString().length > 15){
|
||
alert("房间号太长啦");
|
||
return;
|
||
}
|
||
this.socket.emit('createAndJoin', { room: this.roomId });
|
||
this.isJoined = true;
|
||
// this.nickName = this.genNickName();
|
||
this.addPopup("你进入了房间"+this.roomId);
|
||
this.logs.push("你进入了房间"+this.roomId);
|
||
}
|
||
},
|
||
//退出房间
|
||
exitRoom : function () {
|
||
if (this.roomId) {
|
||
this.socket.emit('exit', {
|
||
from : this.socketId,
|
||
room: this.roomId
|
||
});
|
||
}
|
||
for (let i in this.rtcConns) {
|
||
let rtcConnect = this.rtcConns[i];
|
||
rtcConnect.close();
|
||
rtcConnect = null;
|
||
}
|
||
|
||
window.location.reload();
|
||
},
|
||
//获取rtc缓存连接
|
||
getRtcConnect : function(id){
|
||
return this.rtcConns[id];
|
||
},
|
||
//创立链接
|
||
createRtcConnect : function (id) {
|
||
if(id === undefined){
|
||
return;
|
||
}
|
||
|
||
let that = this;
|
||
let rtcConnect = new RTCPeerConnection(this.config);
|
||
|
||
rtcConnect.onicecandidate = (e) => {
|
||
that.iceCandidate(rtcConnect, id, e)
|
||
};
|
||
|
||
//保存peer连接
|
||
this.rtcConns[id] = rtcConnect;
|
||
if (!this.remoteMap[id]) {
|
||
Vue.set(this.remoteMap,id,{id : id})
|
||
}
|
||
|
||
//数据通道
|
||
this.initSendDataChannel(id);
|
||
|
||
rtcConnect.onremovestream = (e) => {
|
||
that.removeStream(rtcConnect, id, e)
|
||
};
|
||
|
||
return rtcConnect;
|
||
},
|
||
//获取本地与远程连接
|
||
getOrCreateRtcConnect : function(id){
|
||
let rtcConnect = this.getRtcConnect(id);
|
||
if (typeof (rtcConnect) == 'undefined'){
|
||
rtcConnect = this.createRtcConnect(id);
|
||
}
|
||
return rtcConnect;
|
||
},
|
||
//连接创立时建立 send/receive Channel链接
|
||
initSendDataChannel : function (id) {
|
||
let that = this;
|
||
|
||
let sendChannel = this.rtcConns[id].createDataChannel('sendDataChannel');
|
||
sendChannel.binaryType = 'arraybuffer';
|
||
|
||
sendChannel.addEventListener('open', ()=>{
|
||
if (sendChannel.readyState === 'open') {
|
||
that.logs.push("建立连接 : channel open")
|
||
}
|
||
});
|
||
|
||
sendChannel.addEventListener('close', ()=>{
|
||
if (sendChannel.readyState === 'close') {
|
||
that.logs.push("连接关闭 : channel close")
|
||
}
|
||
});
|
||
|
||
sendChannel.addEventListener('error', (error) => {
|
||
that.handlerSendChannelError(error)
|
||
});
|
||
|
||
this.rtcConns[id].addEventListener('datachannel', (event)=>{
|
||
that.initReceiveDataChannel(event,id);
|
||
});
|
||
|
||
this.setRemoteInfo(id,{sendChannel : sendChannel});
|
||
},
|
||
//处理发送过程中的错误情况
|
||
handlerSendChannelError : function(error){
|
||
console.error(error.error)
|
||
this.logs.push("连接断开 : "+error)
|
||
},
|
||
//上传文件
|
||
submitChooseFile : function(){
|
||
this.initSendData();
|
||
},
|
||
//创建发送文件事件
|
||
initSendData : function () {
|
||
let that = this;
|
||
if(this.chooseFile == undefined || this.chooseFile == null){
|
||
this.logs.push("请先选择文件")
|
||
return;
|
||
}
|
||
|
||
this.fileReader = new FileReader();
|
||
this.fileReader.addEventListener('error', error => {
|
||
that.logs.push("读取文件错误 : "+error);
|
||
});
|
||
this.fileReader.addEventListener('abort', event => {
|
||
that.logs.push("读取文件中断 : "+event);
|
||
});
|
||
this.fileReader.addEventListener('load', this.sendData);
|
||
this.readSlice(0);
|
||
},
|
||
/**
|
||
* 发送文件
|
||
* 0 : 未发送
|
||
* 1 : 发送中
|
||
* 2 : 已发送
|
||
* @param {*} event
|
||
*/
|
||
sendData : function(event){
|
||
let needSendingId = "";
|
||
|
||
let hasSending = false;
|
||
for(let id in this.remoteMap){
|
||
let remote = this.remoteMap[id];
|
||
let status = remote.status || 0;
|
||
if(status === 1){ //有正在发送中的
|
||
hasSending = true;
|
||
needSendingId = id;
|
||
}
|
||
}
|
||
|
||
let that = this;
|
||
// hasSending = Object.keys(Object.keys(remoteMap).filter((id)=>{
|
||
// return that.remoteMap[id].status === 1;
|
||
// }));
|
||
|
||
if(!hasSending){ //没有正在发送中的, 取出对应的还没发送的文件
|
||
let hasAllSended = true;
|
||
for(let id in this.remoteMap){
|
||
let remote = this.remoteMap[id];
|
||
let status = remote.status || 0;
|
||
if(status === 0 || status === 1){
|
||
hasAllSended = false;
|
||
this.allSended = true;
|
||
}
|
||
}
|
||
if(hasAllSended){ //全部发送完毕
|
||
return;
|
||
}
|
||
for(let id in this.remoteMap){ //还有还没发送的
|
||
let remote = this.remoteMap[id];
|
||
let status = remote.status || 0;
|
||
if(status === 0){
|
||
needSendingId = id;
|
||
}
|
||
}
|
||
this.setRemoteInfo(needSendingId,{status : 1}) //发送给下一个用户时更新状态
|
||
}
|
||
|
||
|
||
if(needSendingId != ''){
|
||
let remote = this.remoteMap[needSendingId];
|
||
let status = remote.status || 0;
|
||
if(status === 1){ //保证同一时间只能发送房间内对应的一个用户
|
||
let sendChannel = remote.sendChannel;
|
||
if(!sendChannel || sendChannel.readyState !== 'open'){
|
||
return;
|
||
}
|
||
|
||
if(this.offset === 0){
|
||
this.addPopup("正在发送给"+needSendingId.substr(0,4)+",0%。");
|
||
this.logs.push("正在发送给"+needSendingId.substr(0,4)+",0%。")
|
||
}
|
||
|
||
sendChannel.send(event.target.result);
|
||
this.offset += event.target.result.byteLength;
|
||
let currentSendFile = this.offset;
|
||
|
||
//更新发送进度
|
||
this.updateSendProcess(needSendingId, {
|
||
process : parseInt((currentSendFile/this.chooseFile.size)*100)
|
||
})
|
||
|
||
//发送完一份重置相关数据 并且开启下一个
|
||
if(this.offset === this.chooseFile.size){
|
||
console.log(needSendingId+"发送完毕");
|
||
this.addPopup("正在发送给"+needSendingId.substr(0,4)+",100%。");
|
||
this.logs.push("正在发送给"+needSendingId.substr(0,4)+",100%。")
|
||
|
||
//更新发送进度
|
||
this.updateSendProcess(needSendingId, {
|
||
done : true
|
||
})
|
||
|
||
this.offset = 0;
|
||
this.setRemoteInfo(needSendingId,{status : 2})
|
||
this.submitChooseFile();
|
||
}
|
||
}
|
||
}
|
||
},
|
||
//文件分片 -- 点击发送时首次自动,后续就是收到ack回执后自动
|
||
readSlice : function (offset) {
|
||
const slice = this.chooseFile.slice(this.offset, offset + this.chunkSize);
|
||
this.fileReader.readAsArrayBuffer(slice);
|
||
},
|
||
//分片发送反馈ack
|
||
receivedAck : function (socketId, receivedSize) {
|
||
this.socket.emit('message', {
|
||
emitType : "receivedAck",
|
||
room : this.roomId,
|
||
from : this.socketId,
|
||
offset : receivedSize,
|
||
chunkSize : this.chunkSize,
|
||
to : socketId
|
||
});
|
||
},
|
||
//创建接收文件事件
|
||
initReceiveDataChannel : function(event, id){
|
||
if(!id || !event){
|
||
return;
|
||
}
|
||
let currentRtc = this.getRemoteInfo(id);
|
||
if(currentRtc){
|
||
let receiveChannel = event.channel;
|
||
receiveChannel.binaryType = 'arraybuffer';
|
||
receiveChannel.onmessage = (env)=>{
|
||
this.receiveData(env,id);
|
||
};
|
||
receiveChannel.onopen = ()=>{
|
||
const readyState = receiveChannel.readyState;
|
||
if (readyState === 'open') {
|
||
|
||
}
|
||
};
|
||
receiveChannel.onclose = ()=>{
|
||
const readyState = receiveChannel.readyState;
|
||
if (readyState === 'open') {
|
||
|
||
}
|
||
};
|
||
this.setRemoteInfo(id, {receiveChannel : receiveChannel});
|
||
}
|
||
},
|
||
//接收文件
|
||
receiveData :function(event, id) {
|
||
if(!event || !id){
|
||
return;
|
||
}
|
||
let currentRtc = this.getRemoteInfo(id);
|
||
let receiveFiles = currentRtc.receiveFiles || {};
|
||
let name = receiveFiles.name;
|
||
let size = receiveFiles.size;
|
||
let type = receiveFiles.type;
|
||
|
||
//获取数据存下本地
|
||
let receiveBuffer = currentRtc.receiveBuffer || [];
|
||
let receivedSize = currentRtc.receivedSize || 0;
|
||
receiveBuffer.push(event.data);
|
||
receivedSize += event.data.byteLength;
|
||
this.$refs['receiveProgress'].value = receivedSize;
|
||
|
||
this.setRemoteInfo(id,{receiveBuffer : receiveBuffer,receivedSize : receivedSize})
|
||
this.currentReceiveSize += event.data.byteLength;
|
||
|
||
//收到分片后反馈ack
|
||
this.receivedAck(id, receivedSize);
|
||
|
||
//更新接收进度
|
||
this.updateReceiveProcess(id, {
|
||
process : parseInt((receivedSize/size)*100)
|
||
});
|
||
|
||
if(receivedSize === size){
|
||
console.log("接收完毕");
|
||
this.logs.push("接收完毕...");
|
||
this.$refs['receiveProgress'].value = 0;
|
||
this.addPopup("文件[ "+name+" ]接收完毕,可点击右下角查看。");
|
||
|
||
//更新接收进度
|
||
this.updateReceiveProcess(id, {
|
||
style : 'color: #ff5722;text-decoration: underline;',
|
||
href : URL.createObjectURL(new Blob(receiveBuffer),{type: type}),
|
||
done : true
|
||
});
|
||
//清除接收的数据缓存
|
||
this.setRemoteInfo(id,{receiveBuffer : [], receivedSize : 0})
|
||
this.currentReceiveSize = 0;
|
||
}
|
||
},
|
||
//关闭连接
|
||
closeDataChannels : function () {
|
||
for(let remote in this.remoteMap){
|
||
let id = remote.id;
|
||
let sendChannel = remote.sendChannel;
|
||
let receiveChannel = remote.receiveChannel;
|
||
if(!id || !sendChannel || !receiveChannel){
|
||
continue;
|
||
}
|
||
sendChannel.close();
|
||
receiveChannel.close();
|
||
}
|
||
},
|
||
//设置rtc缓存远程连接数据
|
||
setRemoteInfo(id, data){
|
||
if(!id || !data){
|
||
return;
|
||
}
|
||
let oldData = this.remoteMap[id];
|
||
if(oldData){
|
||
Object.assign(oldData,data);
|
||
Vue.set(this.remoteMap, id, oldData);
|
||
}
|
||
},
|
||
//更新接收进度
|
||
updateReceiveProcess : function (id, data) {
|
||
for(let i = 0; i < this.receiveFileList.length; i++){
|
||
let item = this.receiveFileList[i];
|
||
if(item.id === id && !item.done){
|
||
Object.assign(this.receiveFileList[i], data);
|
||
}
|
||
}
|
||
},
|
||
//更新发送进度
|
||
updateSendProcess : function (id, data) {
|
||
for(let i = 0; i < this.sendFileList.length; i++){
|
||
let item = this.sendFileList[i];
|
||
if(item.id === id && !item.done){
|
||
Object.assign(this.sendFileList[i], data);
|
||
}
|
||
}
|
||
},
|
||
//获取rtc缓存远程连接数据
|
||
getRemoteInfo(id){
|
||
if(!id){
|
||
return;
|
||
}
|
||
return this.remoteMap[id];
|
||
},
|
||
//移除rtc连接
|
||
removeStream : function(rtcConnect,id,event){
|
||
this.getOrCreateRtcConnect(id).close;
|
||
delete this.rtcConns[id];
|
||
delete this.remoteMap[id];
|
||
},
|
||
iceCandidate : function (rtcConnect,id,event) {
|
||
if (event.candidate != null) {
|
||
let message = {
|
||
from : this.socketId,
|
||
to : id,
|
||
room : this.roomId,
|
||
sdpMid : event.candidate.sdpMid,
|
||
sdpMLineIndex : event.candidate.sdpMLineIndex,
|
||
sdp : event.candidate.candidate
|
||
};
|
||
this.socket.emit('candidate', message);
|
||
}
|
||
},
|
||
offerSuccess : function (rtcConnect,id,offer) {
|
||
rtcConnect.setLocalDescription(offer).then(r => {})
|
||
let message = {
|
||
from : this.socketId,
|
||
to : id,
|
||
room : this.roomId,
|
||
sdp : offer.sdp
|
||
};
|
||
this.socket.emit('offer', message);
|
||
},
|
||
offerFailed : function (rtcConnect,id,error) {
|
||
this.logs.push("offer失败,"+error);
|
||
},
|
||
answerSuccess : function (rtcConnect,id,offer) {
|
||
rtcConnect.setLocalDescription(offer).then(r => {});
|
||
let message = {
|
||
from : this.socketId,
|
||
to : id,
|
||
room : this.roomId,
|
||
sdp : offer.sdp
|
||
};
|
||
this.socket.emit('answer', message);
|
||
},
|
||
answerFailed : function (rtcConnect,id,error) {
|
||
this.logs.push("answer失败,"+error);
|
||
},
|
||
addIceCandidateSuccess : function(res){
|
||
this.logs.push("addIceCandidateSuccess成功,"+res);
|
||
},
|
||
addIceCandidateFailed : function(err){
|
||
this.logs.push("addIceCandidate失败,"+err);
|
||
},
|
||
socketListener : function () {
|
||
let that = this;
|
||
this.socket.on('created', async function (data) {
|
||
that.logs.push("创建房间,"+JSON.stringify(data));
|
||
that.socketId = data.id;
|
||
that.roomId = data.room;
|
||
for (let i = 0; i < data['peers'].length; i++) {
|
||
let otherSocketId = data['peers'][i].id;
|
||
let rtcConnect = that.getOrCreateRtcConnect(otherSocketId);
|
||
rtcConnect.createOffer(that.options).then(offer => {
|
||
that.offerSuccess(rtcConnect, otherSocketId, offer);
|
||
}, error => {
|
||
that.offerFailed(rtcConnect, otherSocketId, error);
|
||
});
|
||
}
|
||
that.touchResize();
|
||
});
|
||
|
||
this.socket.on('joined', function (data) {
|
||
that.logs.push("加入房间,"+JSON.stringify(data));
|
||
that.getOrCreateRtcConnect(data.from);
|
||
that.addPopup(data.id+"加入了房间。");
|
||
that.touchResize();
|
||
});
|
||
|
||
this.socket.on('offer', function (data) {
|
||
that.logs.push("offer,"+JSON.stringify(data));
|
||
let rtcConnect = that.getOrCreateRtcConnect(data.from);
|
||
let rtcDescription = { type: 'offer', sdp: data.sdp };
|
||
rtcConnect.setRemoteDescription(new RTCSessionDescription(rtcDescription)).then(r => {});
|
||
rtcConnect.createAnswer(that.options).then((offer) => {
|
||
that.answerSuccess(rtcConnect, data.from, offer)
|
||
}).catch((error) => {
|
||
that.answerFailed(rtcConnect, data.from, error)
|
||
});
|
||
});
|
||
|
||
this.socket.on('answer', function (data) {
|
||
that.logs.push("answer,"+JSON.stringify(data));
|
||
let rtcConnect = that.getOrCreateRtcConnect(data.from);
|
||
let rtcDescription = { type: 'answer', sdp: data.sdp };
|
||
rtcConnect.setRemoteDescription(new RTCSessionDescription(rtcDescription)).then(r => {});
|
||
});
|
||
|
||
this.socket.on('candidate', function (data) {
|
||
that.logs.push("candidate,"+JSON.stringify(data));
|
||
let rtcConnect = that.getOrCreateRtcConnect(data.from);
|
||
let rtcIceCandidate = new RTCIceCandidate({
|
||
candidate: data.sdp,
|
||
sdpMid: data.sdpMid,
|
||
sdpMLineIndex: data.sdpMLineIndex
|
||
});
|
||
rtcConnect.addIceCandidate(rtcIceCandidate).then(res => {
|
||
that.addIceCandidateSuccess(res);
|
||
}).catch(error => {
|
||
that.addIceCandidateFailed(error);
|
||
});
|
||
});
|
||
|
||
this.socket.on('exit', function (data) {
|
||
var rtcConnect = that.rtcConns[data.from];
|
||
if (typeof (rtcConnect) == 'undefined') {
|
||
return;
|
||
} else {
|
||
that.addPopup(data.from+"退出了房间。");
|
||
that.logs.push("退出房间,"+JSON.stringify(data));
|
||
that.getOrCreateRtcConnect(data.from).close;
|
||
delete that.rtcConns[data.from];
|
||
Vue.delete(that.remoteMap,data.from);
|
||
}
|
||
that.touchResize();
|
||
})
|
||
|
||
//选中文件时发送给接收方
|
||
this.socket.on('sendFileInfo', function (data) {
|
||
let fromId = data.from;
|
||
that.setRemoteInfo(fromId,{receiveFiles : data});
|
||
that.addPopup(data.from+"选择了文件 [ "+data.name+" ],即将发送。");
|
||
that.logs.push(data.from+"选择了文件 [ "+data.name+" ],即将发送。");
|
||
that.$refs['receiveProgress'].max = data.size;
|
||
|
||
that.receiveFileList.push({
|
||
id : fromId,
|
||
href : "",
|
||
name : data.name,
|
||
type : data.type,
|
||
size : data.size,
|
||
process : 0,
|
||
done : false
|
||
})
|
||
});
|
||
|
||
//收到文件回传ack,继续分片回传
|
||
this.socket.on('receivedAck', function (data) {
|
||
let to = data.to;
|
||
if(to === that.socketId){
|
||
if(that.offset < that.chooseFile.size){
|
||
that.readSlice(that.offset)
|
||
}
|
||
}
|
||
});
|
||
},
|
||
initCss : function(e){
|
||
if(!e) return;
|
||
if(this.currentMenu === 1){
|
||
this.clickHome(false);
|
||
}else if(this.currentMenu === 2){
|
||
this.clickRoom(false);
|
||
}else if(this.currentMenu === 3){
|
||
this.clickFile(false);
|
||
}
|
||
//re caculate size
|
||
this.reCaculateSwiperSize();
|
||
|
||
this.logsHeight = document.documentElement.clientHeight-55;
|
||
},
|
||
loadJS : function( url, callback ){
|
||
var script = document.createElement('script'),
|
||
fn = callback || function(){};
|
||
script.type = 'text/javascript';
|
||
//IE
|
||
if(script.readyState){
|
||
script.onreadystatechange = function(){
|
||
if( script.readyState == 'loaded' || script.readyState == 'complete' ){
|
||
script.onreadystatechange = null;
|
||
fn();
|
||
}
|
||
};
|
||
}else{
|
||
//其他浏览器
|
||
script.onload = function(){
|
||
fn();
|
||
};
|
||
}
|
||
script.src = url;
|
||
document.getElementsByTagName('head')[0].appendChild(script);
|
||
},
|
||
reCaculateSwiperSize : function () {
|
||
let clientWidth = document.body.clientWidth;
|
||
let slidesPerView = parseInt((clientWidth / 100))-1;
|
||
if(window.swiper){
|
||
window.swiper.params.slidesPerView = slidesPerView;
|
||
}
|
||
},
|
||
touchResize : function() {
|
||
let that = this;
|
||
setTimeout(()=>{
|
||
var myEvent = new Event('resize');
|
||
window.dispatchEvent(myEvent);
|
||
that.reCaculateSwiperSize();
|
||
},100)
|
||
}
|
||
},
|
||
created : function () {
|
||
let that = this;
|
||
if(window.location.hash && window.location.hash.includes("debug")){
|
||
this.loadJS('/static/js/vconsole.min.js',function(){
|
||
that.loadJS('/static/js/vconsole.js',function(){
|
||
console.log("load vconsole success")
|
||
});
|
||
});
|
||
}
|
||
},
|
||
mounted : function () {
|
||
this.$nextTick(()=>{
|
||
this.logs.push("socket 初始化中...");
|
||
this.socketListener();
|
||
this.logs.push("socket 初始化成功");
|
||
})
|
||
this.clickHome(false);
|
||
|
||
window.onresize = this.initCss;
|
||
},
|
||
destroyed : function () {
|
||
|
||
}
|
||
});
|
||
})
|
||
|
||
|