diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md deleted file mode 100644 index 4a93f10..0000000 --- a/docs/DEPLOY.md +++ /dev/null @@ -1,78 +0,0 @@ -# 部署 - -## 源 - -``` -cd /etc/yum.repos.d -rm -rf * -wget /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo -yum makecache -``` - -## 证书 - -``` -keytool -genkeypair -keyalg RSA -dname "CN=localhost, OU=acgist, O=taoyao, L=GZ, ST=GD, C=CN" -alias taoyao -validity 3650 -ext ku:c=dig,keyE -ext eku=serverAuth -ext SAN=dns:localhost,ip:127.0.0.1 -keystore taoyao.jks -keypass 123456 -storepass 123456 -``` - -## Linux句柄数量 - -``` -vim /etc/security/limits.conf - -root soft nofile 655350 -root hard nofile 655350 -* soft nofile 655350 -* hard nofile 655350 -* soft nproc 655350 -* hard nproc 655350 -* soft core unlimited -* hard core unlimited -``` - -## Linux内核优化 - -``` -vim /etc/sysctl.conf - -net.ipv4.tcp_tw_reuse = 1 -net.ipv4.tcp_tw_recycle = 1 -net.ipv4.tcp_syncookies = 1 -net.ipv4.tcp_fin_timeout = 30 -net.ipv4.tcp_max_tw_buckets = 8192 -net.ipv4.tcp_max_syn_backlog = 8192 - -# 其他 -net.core.rmem_max -net.core.rmem_default -net.core.wmem_max -net.core.wmem_default -net.core.somaxconn = 1024 -net.core.netdev_max_backlog = 8092 -net.ipv4.udp_mem -net.ipv4.udp_rmem -net.ipv4.udp_wmem -net.ipv4.tcp_mem = 78643200 104857600 157286400 -net.ipv4.tcp_rmem = 873200 1746400 3492800 -net.ipv4.tcp_wmem = 873200 1746400 3492800 - -sysctl -p -``` - -## 应用 - -``` -``` - -## 防火墙 - -``` -firewall-cmd --zone=public --add-port=8888/tcp --permanent -firewall-cmd --zone=public --add-port=45535-65535/tcp --permanent -firewall-cmd --zone=public --add-port=45535-65535/udp --permanent - -firewall-cmd --reload -firewall-cmd --list-ports -firewall-cmd --zone=public --remove-port=45535-65535/tcp --permanent -firewall-cmd --zone=public --remove-port=45535-65535/udp --permanent -``` \ No newline at end of file diff --git a/docs/Deploy.md b/docs/Deploy.md new file mode 100644 index 0000000..42c85e9 --- /dev/null +++ b/docs/Deploy.md @@ -0,0 +1,174 @@ +# 部署 + +## Yum源 + +``` +cd /etc/yum.repos.d +rm -rf * +wget /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo +yum makecache +``` + +## Linux句柄数量 + +``` +vim /etc/security/limits.conf + +root soft nofile 655350 +root hard nofile 655350 +* soft nofile 655350 +* hard nofile 655350 +* soft nproc 655350 +* hard nproc 655350 +* soft core unlimited +* hard core unlimited +``` + +## Linux内核优化 + +``` +vim /etc/sysctl.conf + +net.ipv4.tcp_tw_reuse = 1 +net.ipv4.tcp_tw_recycle = 1 +net.ipv4.tcp_syncookies = 1 +net.ipv4.tcp_fin_timeout = 30 +net.ipv4.tcp_max_tw_buckets = 8192 +net.ipv4.tcp_max_syn_backlog = 8192 + +# 其他 +net.core.rmem_max +net.core.rmem_default +net.core.wmem_max +net.core.wmem_default +net.core.somaxconn = 1024 +net.core.netdev_max_backlog = 8092 +net.ipv4.udp_mem +net.ipv4.udp_rmem +net.ipv4.udp_wmem +net.ipv4.tcp_mem = 78643200 104857600 157286400 +net.ipv4.tcp_rmem = 873200 1746400 3492800 +net.ipv4.tcp_wmem = 873200 1746400 3492800 + +sysctl -p +``` + +## Git + +``` +yum install git +``` + +## Java + +安装之前需要卸载旧版,如果旧版已经是`17+`可以忽略安装。 + +``` +# 下载 +mkdir -p /data/java +cd /data/java +wget https://download.java.net/java/GA/jdk17.0.2/dfd4a8d0985749f896bed50d7138ee7f/8/GPL/openjdk-17.0.2_linux-x64_bin.tar.gz +tar -zxvf openjdk-17.0.2_linux-x64_bin.tar.gz +# 环境变量 +vim ~/.bash_profile +PATH=$PATH:/data/java/jdk-17.0.2/bin +. ~/.bash_profile +ln -sf /data/java/jdk-17.0.2/bin/java /usr/local/bin/java +# 验证 +java -version +``` + +## Maven + +``` +# 下载 +mkdir -p /data/maven +cd /data/maven +wget https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz +tar -zxvf apache-maven-3.8.6-bin.tar.gz +# 环境变量 +vim ~/.bash_profile +PATH=$PATH:/data/maven/apache-maven-3.8.6/bin +. ~/.bash_profile +# 验证 +mvn -version +``` + +## Taoyao + +``` +# 下载源码 +mkdir -p /data/taoyao +cd /data +git clone https://gitee.com/acgist/taoyao.git +cd /data/taoyao/taoyao + +# 编译代码 +mvn clean package -D skipTests +#mvn clean package -D skipTests -P release + +# 拷贝脚本 +cp taoyao-server/target/taoyao-server-1.0.0/bin/deploy.sh ../ + +# 启动服务 +vim /usr/lib/systemd/system/taoyao.service +---- +[Unit] +Description=桃夭 +After=network.target +Wants=network.target + +[Service] +User=root +Type=forking +KillMode=process +ExecStart=/data/taoyao/taoyao-server/bin/startup.sh +ExecReload=/bin/kill -HUP $MAINPID +ExecStop=/bin/kill -QUIT $MAINPID +Restart=always +RestartSec=5s + +[Install] +WantedBy=multi-user.target +---- + +systemctl daemon-reload +systemctl start taoyao +systemctl enable taoyao +``` + +## 防火墙 + +``` +firewall-cmd --zone=public --add-port=8888/tcp --permanent +firewall-cmd --zone=public --add-port=45535-65535/udp --permanent + +firewall-cmd --reload +firewall-cmd --list-ports + +# 删除端口 +firewall-cmd --zone=public --remove-port=8888/udp --permanent +firewall-cmd --zone=public --remove-port=45535-65535/udp --permanent +``` + +## 证书 + +正式环境建议关闭项目`SSL`配置,可以使用`Nginx`配置证书。 + +``` +keytool -genkeypair -keyalg RSA -dname "CN=localhost, OU=acgist, O=taoyao, L=GZ, ST=GD, C=CN" -alias taoyao -validity 3650 -ext ku:c=dig,keyE -ext eku=serverAuth -ext SAN=dns:localhost,ip:127.0.0.1 -keystore taoyao.jks -keypass 123456 -storepass 123456 +``` + +https://www.jianshu.com/p/fa047d7054eb +https://www.jianshu.com/p/59da3d350488 +https://www.jianshu.com/p/fa047d7054eb +https://segmentfault.com/a/1190000039782685 +https://www.cnblogs.com/bolingcavalry/p/15473808.html +http://www.manoner.com/post/音视频基础/WebRTC核心组件和协议栈/ +https://blog.csdn.net/eguid_1/article/details/117277841 +https://blog.csdn.net/xiang_6119/article/details/108779678 +https://blog.csdn.net/qq_40321119/article/details/108336324 +https://blog.csdn.net/ababab12345/article/details/115585378 +https://blog.csdn.net/jisuanji111111/article/details/121634199 +https://blog.csdn.net/weixin_48638578/article/details/120191152 +https://blog.csdn.net/weixin_45565568/article/details/108929438 diff --git a/docs/LINK.md b/docs/LINK.md deleted file mode 100644 index ba1f7e3..0000000 --- a/docs/LINK.md +++ /dev/null @@ -1,12 +0,0 @@ -https://www.jianshu.com/p/fa047d7054eb -https://www.jianshu.com/p/59da3d350488 -https://segmentfault.com/a/1190000039782685 -https://www.cnblogs.com/bolingcavalry/p/15473808.html -http://www.manoner.com/post/音视频基础/WebRTC核心组件和协议栈/ -https://blog.csdn.net/eguid_1/article/details/117277841 -https://blog.csdn.net/xiang_6119/article/details/108779678 -https://blog.csdn.net/qq_40321119/article/details/108336324 -https://blog.csdn.net/ababab12345/article/details/115585378 -https://blog.csdn.net/jisuanji111111/article/details/121634199 -https://blog.csdn.net/weixin_48638578/article/details/120191152 -https://blog.csdn.net/weixin_45565568/article/details/108929438 diff --git a/docs/bin/deploy.sh b/docs/bin/deploy.sh index 80be3ee..0aab987 100644 --- a/docs/bin/deploy.sh +++ b/docs/bin/deploy.sh @@ -15,22 +15,23 @@ fi # 编译代码 if [ -z $mvned ]; then echo "编译代码:${project.artifactId}-${project.version}" - mvn clean package install -pl "${project.groupId}:${project.artifactId}" -am -D skipTests -P ${env} + cd $base/taoyao + mvn clean package -D skipTests -P ${profile} fi # 删除文件:注意不要删除日志 -rm -rf $base/../deploy/${project.artifactId}/bin -rm -rf $base/../deploy/${project.artifactId}/lib -rm -rf $base/../deploy/${project.artifactId}/config +rm -rf $base/${project.artifactId}/bin +rm -rf $base/${project.artifactId}/lib +rm -rf $base/${project.artifactId}/config # 运行目录 echo "拷贝文件:${project.artifactId}-${project.version}" -if [ ! -d "$base/../deploy/${project.artifactId}" ]; then - mkdir -p $base/../deploy/${project.artifactId} +if [ ! -d "$base/${project.artifactId}" ]; then + mkdir -p $base/${project.artifactId} fi # 拷贝文件 -cp -rf ${project.basedir}/target/${project.artifactId}-${project.version}/* $base/../deploy/${project.artifactId} +cp -rf ${project.basedir}/target/${project.artifactId}-${project.version}/* $base/${project.artifactId} # 启动服务 -#cd $base/../deploy/${project.artifactId} +#cd $base/${project.artifactId} #sh bin/startup.sh systemctl restart taoyao diff --git a/docs/bin/taoyao.service b/docs/bin/taoyao.service deleted file mode 100644 index f446872..0000000 --- a/docs/bin/taoyao.service +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=桃夭 -After=network.target -Wants=network.target - -[Service] -User=root -Type=forking -KillMode=process -ExecStart=/data/taoyao/bin/startup.sh -ExecReload=/bin/kill -HUP $MAINPID -ExecStop=/bin/kill -QUIT $MAINPID -Restart=always -RestartSec=5s - -[Install] -WantedBy=multi-user.target diff --git a/pom.xml b/pom.xml index d441bff..fa1d8eb 100644 --- a/pom.xml +++ b/pom.xml @@ -23,9 +23,9 @@ 17 - 1.18.24 1.5.8 5.1.2 + 1.18.24 6.18.0 1.6.12 1.5.3.Final diff --git a/taoyao-server/src/main/resources/application.yml b/taoyao-server/src/main/resources/application.yml index c384cee..c7078f2 100644 --- a/taoyao-server/src/main/resources/application.yml +++ b/taoyao-server/src/main/resources/application.yml @@ -2,7 +2,6 @@ server: port: 8888 http2: enabled: true - # 如果Nginx代理可以不用配置SSL提升性能 ssl: key-alias: taoyao key-store: classpath:taoyao.jks diff --git a/taoyao-server/src/main/resources/static/javascript/taoyao.js b/taoyao-server/src/main/resources/static/javascript/taoyao.js index 05bc143..778454f 100644 --- a/taoyao-server/src/main/resources/static/javascript/taoyao.js +++ b/taoyao-server/src/main/resources/static/javascript/taoyao.js @@ -1,24 +1,18 @@ /** 桃夭WebRTC终端核心功能 */ -/** 配置 */ -const taoyaoConfig = { - // 当前终端SN - sn: 'taoyao', - // 信令授权 - username: 'taoyao', - password: 'taoyao' -}; -/** 音频配置 */ +/** 兼容 */ +const PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; +/** 默认音频配置 */ const defaultAudioConfig = { // 音量:0~1 volume: 0.5, // 设备 // deviceId : '', // 采样率:8000|16000|32000|48000 - sampleRate: 32000, + sampleRate: 48000, // 采样数:16 sampleSize: 16, // 延迟大小(单位毫秒):500毫秒以内较好 - latency: 0.3, + latency: 0.4, // 声道数量:1|2 channelCount : 1, // 是否开启自动增益:true|false @@ -30,7 +24,7 @@ const defaultAudioConfig = { // 消除回音方式:system|browser echoCancellationType: 'system' }; -/** 视频配置 */ +/** 默认视频配置 */ const defaultVideoConfig = { // 宽度 width: 1280, @@ -45,9 +39,244 @@ const defaultVideoConfig = { // 选摄像头:user|left|right|environment facingMode: 'environment' } -/** 兼容 */ -const XMLHttpRequest = window.XMLHttpRequest; -const PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; +/** 信令配置 */ +const signalConfig = { + /** 当前终端SN */ + sn: 'taoyao', + /** 当前版本 */ + version: '1.0.0', + // 信令授权 + username: 'taoyao', + password: 'taoyao' +}; +/** 信令协议 */ +const signalProtocol = { + /** 直播信令 */ + live: { + }, + /** 媒体信令 */ + media: { + }, + /** 终端信令 */ + client: { + /** 注册 */ + register: 2000, + /** 下发配置 */ + config: 2004, + /** 心跳 */ + heartbeat: 2005, + }, + /** 会议信令 */ + meeting: { + }, + /** 平台信令 */ + platform: { + }, + /** 当前索引 */ + index: 100000, + /** 最小索引 */ + minIndex: 100000, + /** 最大索引 */ + maxIndex: 999999, + /** 生成索引 */ + buildId: function() { + if(this.index++ >= this.maxIndex) { + this.index = this.minIndex; + } + return Date.now() + '' + this.index; + }, + /** 生成信令消息 */ + buildProtocol: function(sn, pid, body, id) { + let message = { + header: { + v: signalConfig.version, + id: id || this.buildId(), + sn: sn, + pid: pid, + }, + 'body': body + }; + return message; + } +}; +/** 信令通道 */ +const signalChannel = { + /** 桃夭 */ + taoyao: null, + /** 通道 */ + channel: null, + /** 地址 */ + address: null, + /** 回调 */ + callback: null, + /** 回调事件 */ + callbackMapping: new Map(), + /** 心跳时间 */ + heartbeatTime: 30 * 1000, + /** 心跳定时器 */ + heartbeatTimer: null, + /** 重连定时器 */ + reconnectTimer: null, + /** 防止重复重连 */ + lockReconnect: false, + /** 当前重连时间 */ + connectionTimeout: 5 * 1000, + /** 最小重连时间 */ + minReconnectionDelay: 5 * 1000, + /** 最大重连时间 */ + maxReconnectionDelay: 60 * 1000, + /** 重连失败时间增长倍数 */ + reconnectionDelayGrowFactor: 2, + /** 心跳 */ + heartbeat: function() { + let self = this; + if(self.heartbeatTimer) { + clearTimeout(self.heartbeatTimer); + } + self.heartbeatTimer = setTimeout(function() { + if (self.channel && self.channel.readyState == WebSocket.OPEN) { + self.push(signalProtocol.buildProtocol( + signalConfig.sn, + signalProtocol.client.heartbeat, + { + signal: 100, + battery: 100 + } + )); + self.heartbeat(); + } else { + console.warn('发送心跳失败', self.channel); + } + }, self.heartbeatTime); + }, + /** 连接 */ + connect: function(address, callback, reconnection = true) { + let self = this; + self.address = address; + self.callback = callback; + return new Promise((resolve, reject) => { + console.debug('连接信令通道', address); + self.channel = new WebSocket(address); + self.channel.onopen = function(e) { + console.debug('打开信令通道', e); + // 注册终端 + self.push(signalProtocol.buildProtocol( + signalConfig.sn, + signalProtocol.client.register, + { + ip: null, + mac: null, + signal: 100, + battery: 100, + username: signalConfig.username, + password: signalConfig.password + } + )); + // 重置时间 + self.connectionTimeout = self.minReconnectionDelay + // 开始心跳 + self.heartbeat(); + // 成功回调 + resolve(e); + }; + self.channel.onclose = function(e) { + console.error('信令通道关闭', self.channel, e); + if(reconnection) { + self.reconnect(); + } + reject(e); + }; + self.channel.onerror = function(e) { + console.error('信令通道异常', self.channel, e); + if(reconnection) { + self.reconnect(); + } + reject(e); + }; + self.channel.onmessage = function(e) { + console.debug('信令通道消息', e.data); + let done = false; + let data = JSON.parse(e.data); + // 注册回调 + if(self.callback) { + done = self.callback(data); + } + // 默认回调 + if(!done) { + self.defaultCallback(data); + } + // 请求回调 + if(self.callbackMapping.has(data.header.id)) { + self.callbackMapping.get(data.header.id)(); + self.callbackMapping.delete(data.header.id); + } + }; + }); + }, + /** 重连 */ + reconnect: function() { + let self = this; + if (self.lockReconnect) { + return; + } + self.lockReconnect = true; + // 关闭旧的通道 + if(self.channel && self.channel.readyState == WebSocket.OPEN) { + self.channel.close(); + self.channel = null; + } + if(self.reconnectTimer) { + clearTimeout(self.reconnectTimer); + } + // 打开定时重连 + self.reconnectTimer = setTimeout(function() { + console.info('信令通道重连', self.address, new Date()); + self.connect(self.address, self.callback, true); + self.lockReconnect = false; + }, self.connectionTimeout); + if (self.connectionTimeout >= self.maxReconnectionDelay) { + self.connectionTimeout = self.maxReconnectionDelay; + } else { + self.connectionTimeout = self.connectionTimeout * self.reconnectionDelayGrowFactor + } + }, + /** 发送消息 */ + push: function(data, callback) { + // 注册回调 + if(data && callback) { + this.callbackMapping.set(data.header.id, callback); + } + // 发送消息 + if(data && data.header) { + this.channel.send(JSON.stringify(data)); + } else { + this.channel.send(data); + } + }, + /** 关闭通道 */ + close: function() { + clearTimeout(this.heartbeatTimer); + }, + /** 默认回调 */ + defaultCallback: function(data) { + console.debug('没有适配信令消息默认处理', data); + switch(data.header.pid) { + case signalProtocol.client.register: + console.debug('终端注册成功'); + break; + case signalProtocol.client.config: + if(this.taoyao) { + this.taoyao + .configMedia(data.body.media) + .configWebrtc(data.body.webrtc); + } + break; + case signalProtocol.client.heartbeat: + console.debug('心跳'); + break; + } + } +}; /** 桃夭 */ function Taoyao( webSocket, @@ -55,7 +284,9 @@ function Taoyao( audioConfig, videoConfig ) { + /** WebSocket地址 */ this.webSocket = webSocket; + /** IceServer地址 */ this.iceServer = iceServer; /** 媒体状态 */ this.audioStatus = true; @@ -87,12 +318,16 @@ function Taoyao( let videoDevice = false; list.forEach(v => { console.debug('终端媒体设备', v.kind, v.label); - if(v.kind === 'audioinput') { + switch(v.kind) { + case 'audioinput': audioDevice = true; - } else if(v.kind === 'videoinput') { + break; + case 'videoinput': videoDevice = true; - } else { + break; + default: console.debug('没有适配设备', v.kind, v.label); + break; } }); if(!audioDevice) { @@ -105,76 +340,41 @@ function Taoyao( } }) .catch(e => { - console.error('获取终端设备失败', e); + console.error('检查终端设备异常', e); self.videoEnabled = false; self.videoEnabled = false; }); } return this; }; - /** 请求 */ - this.request = function(url, data = {}, method = 'GET', async = true, timeout = 5000, mime = 'json') { - return new Promise((resolve, reject) => { - let xhr = new XMLHttpRequest(); - xhr.open(method, url, async); - if(async) { - xhr.timeout = timeout; - xhr.responseType = mime; - xhr.send(data); - xhr.onload = function() { - let response = xhr.response; - if(xhr.readyState === 4 && xhr.status === 200) { - if(response.code === '0000') { - resolve(response.body); - } else { - reject(response.body || response); - } - } else { - reject(response.body || response); - } - } - xhr.onerror = reject; - } else { - xhr.send(data); - let response; - try { - response = JSON.parse(xhr.response); - } catch(e) { - console.error('响应解析失败', xhr); - response = xhr.response; - } - if(xhr.readyState === 4 && xhr.status === 200) { - resolve(response.body || response); - } else { - reject(response.body || response); - } - } - }); - }; /** 媒体配置 */ this.configMedia = function(audio = {}, video = {}) { this.audioConfig = {...this.audioConfig, ...audio}; this.videoCofnig = {...this.videoCofnig, ...video}; console.debug('终端媒体配置', this.audioConfig, this.videoConfig); + return this; }; /** WebRTC配置 */ this.configWebrtc = function(config = {}) { this.webSocket = config.signalAddress; this.iceServer = config.stun; console.debug('WebRTC配置', this.webSocket, this.iceServer); + return this; }; - /** 信令通道 */ + /** 打开信令通道 */ this.buildChannel = function(callback) { + signalChannel.taoyao = this; this.signalChannel = signalChannel; this.signalChannel.connect(this.webSocket, callback); // 不能直接this.push = this.signalChannel.push这样导致this对象错误 this.push = function(data, callback) { this.signalChannel.push(data, callback) }; + return this; }; - /** 本地媒体 */ + /** 打开本地媒体 */ this.buildLocalMedia = function() { - console.debug("获取终端媒体:", this.audioConfig, this.videoConfig); + console.debug('打开终端媒体', this.audioConfig, this.videoConfig); let self = this; return new Promise((resolve, reject) => { if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { @@ -190,11 +390,11 @@ function Taoyao( video: self.videoConfig }, resolve, reject); } else { - reject("获取终端媒体失败"); + reject('打开本地媒体失败'); } }); }; - /** 本地媒体 */ + /** 设置本地媒体 */ this.localMedia = async function(localVideoId, stream) { this.localVideo = document.getElementById(localVideoId); if ('srcObject' in this.localVideo) { @@ -215,195 +415,6 @@ function Taoyao( /** 媒体 */ /** 视频 */ }; -/** 信令协议 */ -const protocol = { - pid: { - /** 心跳 */ - heartbeat: 2005, - /** 注册 */ - register: 2000 - }, - /** 当前索引 */ - index: 100000, - /** 最小索引 */ - minIndex: 100000, - /** 最大索引 */ - maxIndex: 999999, - /** 生成ID */ - buildId: function() { - if(this.index++ >= this.maxIndex) { - this.index = this.minIndex; - } - return Date.now() + '' + this.index; - }, - /** 生成协议 */ - buildProtocol: function(sn, pid, body) { - let message = { - header: { - v: '1.0.0', - id: this.buildId(), - sn: sn, - pid: pid, - }, - "body": body - }; - return message; - } -}; -/** 信令消息 */ -/** 信令通道 */ -const signalChannel = { - /** 通道 */ - channel: null, - /** 地址 */ - address: null, - /** 回调 */ - callback: null, - /** 回调事件 */ - callbackMapping: new Map(), - /** 心跳时间 */ - heartbeatTime: 30 * 1000, - /** 心跳定时器 */ - heartbeatTimer: null, - /** 防止重连 */ - lockReconnect: false, - /** 重连时间 */ - connectionTimeout: 5 * 1000, - /** 最小重连时间 */ - minReconnectionDelay: 5 * 1000, - /** 最大重连时间 */ - maxReconnectionDelay: 60 * 1000, - /** 自动重连失败后重连时间增长倍数 */ - reconnectionDelayGrowFactor: 2, - /** 关闭 */ - close: function() { - clearTimeout(this.heartbeatTimer); - }, - /** 心跳 */ - heartbeat: function() { - let self = this; - self.heartbeatTimer = setTimeout(function() { - if (self.channel && self.channel.readyState == WebSocket.OPEN) { - self.push(protocol.buildProtocol( - taoyaoConfig.sn, - protocol.pid.heartbeat, - { - signal: 100, - battery: 100 - } - )); - self.heartbeat(); - } else { - console.warn('发送心跳失败', self.channel); - } - }, self.heartbeatTime); - }, - /** 重连 */ - reconnect: function() { - let self = this; - if (self.lockReconnect) { - return; - } - self.lockReconnect = true; - // 关闭旧的通道 - if(self.channel && self.channel.readyState == WebSocket.OPEN) { - self.channel.close(); - self.channel = null; - } - // 打开定时重连 - setTimeout(function() { - console.info('信令通道重连', self.address); - self.connect(self.address, self.callback, true); - self.lockReconnect = false; - }, self.connectionTimeout); - if (self.connectionTimeout >= self.maxReconnectionDelay) { - self.connectionTimeout = self.maxReconnectionDelay; - } else { - self.connectionTimeout = self.connectionTimeout * self.reconnectionDelayGrowFactor - } - }, - /** 连接 */ - connect: function(address, callback, reconnection = true) { - let self = this; - this.address = address; - this.callback = callback; - console.debug("连接信令通道", address); - return new Promise((resolve, reject) => { - self.channel = new WebSocket(address); - self.channel.onopen = function(e) { - console.debug('信令通道打开', e); - self.push(protocol.buildProtocol( - taoyaoConfig.sn, - protocol.pid.register, - { - ip: null, - mac: null, - signal: 100, - battery: 100, - username: taoyaoConfig.username, - password: taoyaoConfig.password - } - )); - self.connectionTimeout = self.minReconnectionDelay - self.heartbeat(); - resolve(e); - }; - self.channel.onclose = function(e) { - console.error('信令通道关闭', self.channel, e); - if(reconnection) { - self.reconnect(); - } - reject(e); - }; - self.channel.onerror = function(e) { - console.error('信令通道异常', self.channel, e); - if(reconnection) { - self.reconnect(); - } - reject(e); - }; - self.channel.onmessage = function(e) { - console.debug('信令消息', e.data); - let data = JSON.parse(e.data); - // 注册回调 - let done = false; - if(callback) { - done = callback(data); - } - // 请求回调 - if(self.callbackMapping.has(data.header.id)) { - self.callbackMapping.get(data.header.id)(); - self.callbackMapping.delete(data.header.id); - } - // 默认回调 - done || this.defaultCallback(data); - }; - }); - }, - /** 信令消息 */ - push: function(data, callback) { - // 注册回调 - if(data && callback) { - this.callbackMapping.set(data.header.id, callback); - } - // 发送请求 - if(data && data.header) { - this.channel.send(JSON.stringify(data)); - } else { - this.channel.send(data); - } - }, - /** 默认回调 */ - defaultCallback: function(data) { - console.debug('没有适配信令消息默认处理', data); - switch(data.header.pid) { - case protocol.pid.heartbeat: - break; - case protocol.pid.register: - break; - } - } -}; /* var peer; var socket; // WebSocket diff --git a/taoyao-server/src/main/resources/static/meeting.html b/taoyao-server/src/main/resources/static/meeting.html index e14d7ab..0c2b23a 100644 --- a/taoyao-server/src/main/resources/static/meeting.html +++ b/taoyao-server/src/main/resources/static/meeting.html @@ -50,31 +50,20 @@ child.innerHTML = template; list.appendChild(child); } - const taoyao = new Taoyao(); + const taoyao = new Taoyao("wss://localhost:8888/websocket.signal"); // 检查设备 - taoyao.checkDevice(); - // 配置媒体 - taoyao.request('/config/media', {}, 'GET', false) - .then(response => { - taoyao.configMedia(response.audio, response.video); - }) - .catch(e => console.error('获取媒体配置失败', e)); - // 配置WebRTC - taoyao.request('/config/webrtc', {}, 'GET', false) - .then(response => { - taoyao.configWebrtc(response); - taoyao.buildChannel(callback); - }) - .catch(e => console.error('获取WebRTC配置失败', e)); + taoyao + .checkDevice() + .buildChannel(callback) + //.buildLocalMedia() + //.then(stream => taoyao.localMedia('local', stream)) + //.catch((e) => alert('获取终端媒体失败:' + e)); // 信令回调 function callback(data) { switch(data.header.pid) { - case protocol.pid.heartbeat: + case signalProtocol.client.heartbeat: // 心跳 return true; - case protocol.pid.register: - // 注册 - return true; } return false; } @@ -92,19 +81,13 @@ } // 录制视频 function record(e) { - taoyao.push(protocol.buildProtocol(taoyaoConfig.sn, protocol.pid.heartbeat), () => { + taoyao.push(signalProtocol.buildProtocol(signalConfig.sn, signalProtocol.client.heartbeat), () => { classSwitch(e, 'active'); }); } // 踢出会议 function kick() { } - // 信令通道 - /* - taoyao.buildLocalMedia() - .then(stream => taoyao.localMedia('local', stream)) - .catch((e) => alert('获取终端媒体失败:' + e)); - */ \ No newline at end of file diff --git a/taoyao-signal/README.md b/taoyao-signal/README.md index 345d164..d7e21cf 100644 --- a/taoyao-signal/README.md +++ b/taoyao-signal/README.md @@ -48,6 +48,17 @@ ## 终端信令(2000~2999) +``` +# 终端信息 +{ + "sn": "终端标识", + "ip": "IP地址", + "mac": "MAC地址", + "signal": "信号强度", + "battery": "电池电量" +} +``` + ### 注册信令(2000) 终端->服务端:注册成功后服务端响应,同时下发配置信息,广播终端上线事件。