This commit is contained in:
acgist
2022-11-18 21:42:28 +08:00
parent 7ebac2e092
commit e803d14505
10 changed files with 467 additions and 395 deletions

View File

@@ -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
```

174
docs/Deploy.md Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -23,9 +23,9 @@
<properties>
<!-- 版本 -->
<java.version>17</java.version>
<lombok.version>1.18.24</lombok.version>
<javacv.version>1.5.8</javacv.version>
<ffmpeg.version>5.1.2</ffmpeg.version>
<lombok.version>1.18.24</lombok.version>
<kurento.version>6.18.0</kurento.version>
<springdoc.version>1.6.12</springdoc.version>
<mapstruct.version>1.5.3.Final</mapstruct.version>

View File

@@ -2,7 +2,6 @@ server:
port: 8888
http2:
enabled: true
# 如果Nginx代理可以不用配置SSL提升性能
ssl:
key-alias: taoyao
key-store: classpath:taoyao.jks

View File

@@ -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

View File

@@ -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));
*/
</script>
</body>
</html>

View File

@@ -48,6 +48,17 @@
## 终端信令2000~2999
```
# 终端信息
{
"sn": "终端标识",
"ip": "IP地址",
"mac": "MAC地址",
"signal": "信号强度",
"battery": "电池电量"
}
```
### 注册信令2000
终端->服务端:注册成功后服务端响应,同时下发配置信息,广播终端上线事件。