From e1d497f28eda96dda9f3f889e13d1c2863bf6cbf Mon Sep 17 00:00:00 2001
From: acgist <289547414@qq.com>
Date: Thu, 17 Nov 2022 07:06:07 +0800
Subject: [PATCH] =?UTF-8?q?[+]=20=E5=8D=8F=E8=AE=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 53 +-----
docs/FFmpeg.md | 92 ++++++++++
docs/LINK.md | 12 ++
pom.xml | 71 +++++++-
taoyao-boot/pom.xml | 9 +-
.../boot/config/SecurityProperties.java | 4 +
.../taoyao/boot/config/TaoyaoProperties.java | 2 +-
.../com/acgist/taoyao/boot/model/Message.java | 30 +++-
taoyao-live/pom.xml | 2 +-
.../java/com/acgist/taoyao/live/Live.java | 17 ++
.../com/acgist/taoyao/live/LiveManager.java | 5 +
.../live/controller/LiveController.java | 33 ++++
taoyao-media/README.md | 1 +
taoyao-media/pom.xml | 14 ++
.../media/process/AggregateProcessor.java | 10 ++
.../taoyao/media/process/Processor.java | 5 +
.../taoyao/media/process/ProcessorChain.java | 5 +
.../media/process/audio/DenoiseProcessor.java | 10 ++
.../media/process/audio/MixProcessor.java | 10 ++
.../media/process/audio/WhineProcessor.java | 10 ++
.../media/process/video/BeautyHandler.java | 10 ++
.../media/process/video/MarkHandler.java | 10 ++
.../media/process/video/WatermarkHandler.java | 10 ++
taoyao-meeting/pom.xml | 2 +-
.../com/acgist/taoyao/meeting/Meeting.java | 17 ++
.../acgist/taoyao/meeting/MeetingManager.java | 10 ++
.../meeting/controller/MeetingController.java | 33 ++++
.../com/acgist/taoyao/meeting/room/Room.java | 10 --
taoyao-server/pom.xml | 10 +-
.../config/TaoyaoAutoConfiguration.java | 2 +
.../taoyao/controller/ConfigController.java | 14 +-
.../src/main/resources/application.yml | 1 +
.../resources/static/javascript/taoyao.js | 97 ++++++++---
.../src/main/resources/static/meeting.html | 9 +-
.../signal/protocol/ScriptProtocolTest.java | 27 +++
.../signal/protocol/ShutdownProtocolTest.java | 25 +++
taoyao-signal/README.md | 164 ++++++++++++++++--
taoyao-signal/pom.xml | 2 +-
.../{session => client}/ClientSession.java | 6 +-
.../ClientSessionAdapter.java | 9 +-
.../ClientSessionManager.java | 39 ++++-
.../ClientSessionStatus.java | 2 +-
.../socket/SocketSession.java | 4 +-
.../socket/SocketSignal.java | 2 +-
.../websocket/WebSocketSession.java | 4 +-
.../websocket/WebSocketSignal.java | 6 +-
.../config/SignalAutoConfiguration.java | 2 +-
.../signal/controller/ClientController.java | 33 ++++
.../signal/event/ApplicationEventAdapter.java | 48 +++++
.../signal/event/client/CloseEvent.java | 25 +++
.../signal/event/client/RegisterEvent.java | 29 +---
.../signal/event/platform/ScriptEvent.java | 22 +++
.../listener/ApplicationListenerAdapter.java | 8 +-
.../signal/listener/client/CloseListener.java | 50 ++++++
.../listener/client/RegisterListener.java | 23 +--
.../listener/platform/ScriptListener.java | 66 +++++++
.../taoyao/signal/protocol/Protocol.java | 80 +++++++--
.../signal/protocol/ProtocolAdapter.java | 77 ++++++--
.../protocol/ProtocolBodyMapAdapter.java | 44 -----
...tAdapter.java => ProtocolJavaAdapter.java} | 19 +-
.../signal/protocol/ProtocolManager.java | 56 +++---
.../signal/protocol/ProtocolMapAdapter.java | 40 +++++
.../protocol/client/BroadcastProtocol.java | 36 ++++
.../signal/protocol/client/CloseProtocol.java | 21 ++-
.../protocol/client/HeartbeatProtocol.java | 39 +++++
.../signal/protocol/client/ListProtocol.java | 37 ++++
.../protocol/client/OfflineProtocol.java | 23 ++-
.../protocol/client/OnlineProtocol.java | 11 +-
.../protocol/client/RegisterProtocol.java | 21 ++-
.../protocol/client/StatusProtocol.java | 53 ++++++
.../protocol/client/UnicastProtocol.java | 47 +++++
.../protocol/platform/ErrorProtocol.java | 56 ++++++
.../protocol/platform/ScriptProtocol.java | 34 ++++
.../protocol/platform/ShutdownProtocol.java | 42 +++++
.../signal/protocol/system/ErrorProtocol.java | 32 ----
.../protocol/system/HeartbeatProtocol.java | 33 ----
.../CostedTestTestExecutionListener.java | 3 +
taoyao-webrtc/README.md | 5 -
taoyao-webrtc/pom.xml | 2 +-
79 files changed, 1650 insertions(+), 387 deletions(-)
create mode 100644 docs/FFmpeg.md
create mode 100644 docs/LINK.md
create mode 100644 taoyao-live/src/main/java/com/acgist/taoyao/live/Live.java
create mode 100644 taoyao-live/src/main/java/com/acgist/taoyao/live/LiveManager.java
create mode 100644 taoyao-live/src/main/java/com/acgist/taoyao/live/controller/LiveController.java
create mode 100644 taoyao-media/README.md
create mode 100644 taoyao-media/src/main/java/com/acgist/taoyao/media/process/AggregateProcessor.java
create mode 100644 taoyao-media/src/main/java/com/acgist/taoyao/media/process/Processor.java
create mode 100644 taoyao-media/src/main/java/com/acgist/taoyao/media/process/ProcessorChain.java
create mode 100644 taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/DenoiseProcessor.java
create mode 100644 taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/MixProcessor.java
create mode 100644 taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/WhineProcessor.java
create mode 100644 taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/BeautyHandler.java
create mode 100644 taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/MarkHandler.java
create mode 100644 taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/WatermarkHandler.java
create mode 100644 taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java
create mode 100644 taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java
create mode 100644 taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/controller/MeetingController.java
delete mode 100644 taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/room/Room.java
create mode 100644 taoyao-server/src/test/java/com/acgist/taoyao/signal/protocol/ScriptProtocolTest.java
create mode 100644 taoyao-server/src/test/java/com/acgist/taoyao/signal/protocol/ShutdownProtocolTest.java
rename taoyao-signal/src/main/java/com/acgist/taoyao/signal/{session => client}/ClientSession.java (95%)
rename taoyao-signal/src/main/java/com/acgist/taoyao/signal/{session => client}/ClientSessionAdapter.java (93%)
rename taoyao-signal/src/main/java/com/acgist/taoyao/signal/{session => client}/ClientSessionManager.java (74%)
rename taoyao-signal/src/main/java/com/acgist/taoyao/signal/{session => client}/ClientSessionStatus.java (90%)
rename taoyao-signal/src/main/java/com/acgist/taoyao/signal/{session => client}/socket/SocketSession.java (84%)
rename taoyao-signal/src/main/java/com/acgist/taoyao/signal/{session => client}/socket/SocketSignal.java (61%)
rename taoyao-signal/src/main/java/com/acgist/taoyao/signal/{session => client}/websocket/WebSocketSession.java (85%)
rename taoyao-signal/src/main/java/com/acgist/taoyao/signal/{session => client}/websocket/WebSocketSignal.java (93%)
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/ApplicationEventAdapter.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/CloseEvent.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/ScriptEvent.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/CloseListener.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/ScriptListener.java
delete mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolBodyMapAdapter.java
rename taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/{ProtocolBodyObjectAdapter.java => ProtocolJavaAdapter.java} (59%)
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMapAdapter.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/BroadcastProtocol.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/HeartbeatProtocol.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ListProtocol.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/StatusProtocol.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/UnicastProtocol.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ErrorProtocol.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ScriptProtocol.java
create mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ShutdownProtocol.java
delete mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/ErrorProtocol.java
delete mode 100644 taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/HeartbeatProtocol.java
diff --git a/README.md b/README.md
index 72d08d5..261a3a5 100644
--- a/README.md
+++ b/README.md
@@ -3,21 +3,17 @@
基于WebRTC实现信令服务,实现Mesh、MCU和SFU三种媒体通信架构,支持直播会议两种场景。
项目提供WebRTC服务信令,终端已有H5示例,其他终端需要自己实现。
-## 授权
-
-开源公益免费,商用需要购买授权。
-
## 模块
|模块|名称|描述|
|:--|:--|:--|
|taoyao|桃夭|桃之夭夭灼灼其华|
-|taoyao-boot|启动模块|基础模块|
+|taoyao-boot|基础模块|基础模块|
|taoyao-live|直播|直播、连麦|
|taoyao-test|测试|测试工具|
-|taoyao-media|媒体|录制、视频(美颜、AI识别)、音频(混音、变声、降噪)|
+|taoyao-media|媒体|录制、视频(水印、美颜、AI识别)、音频(降噪、混音、变声)|
|taoyao-signal|信令|信令服务|
-|taoyao-server|服务|启动服务|
+|taoyao-server|启动服务|启动服务|
|taoyao-meeting|会议|会议模式、广播模式、单人对讲|
|taoyao-webrtc|WebRTC模块|WebRTC模块|
|taoyao-webrtc-sfu|WebRTC SFU架构|SFU架构|
@@ -36,15 +32,15 @@
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| taoyao-live | taoyao-meeting |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| taoyao-signal |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| taoyao-media |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| taoyao-mcu / taoyao-sfu | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ taoyao-mesh +
| taoyao-jitsi / taoyao-kurento | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| taoyao-boot |
+| taoyao-signal |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| taoyao-boot |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```
@@ -54,50 +50,19 @@
> 只有公网Mesh架构才需要真正的内网穿透
-## 信令
-
-|功能|描述|标识|响应|
-|:--|:--|:--|:--|
-|注册|终端注册(同步信息)|||
-|关闭|终端关闭(注销)|||
-|心跳|终端心跳|||
-|创建会议|创建会议||返回会议ID|
-|进入会议|没有会议自动创建||返回会议终端同时广播进入消息|
-|离开会议|离开会议||广播离开消息|
-|关闭会议|关闭会议(踢出所有人员)||广播关闭消息|
-|终端列表|||返回所有终端列表|
-|会议终端列表|||返回所有会议终端列表|
-|直播终端列表|||返回所有直播终端列表|
-|邀请终端|会议邀请终端(主动/被动)||单播邀请|
-|踢出终端|会议踢出终端||单播踢出|
-|开启直播||||
-|关闭直播||||
-|发布|控制终端推流|||
-|取消发布|控制终端暂停推流|||
-|订阅|订阅终端媒体流|||
-|取消订阅|取消订阅终端媒体流|||
-|暂停媒体流|暂停终端媒体流分流(不关媒体流通道)|||
-|恢复媒体流|恢复终端媒体流分流(不关媒体流通道)|||
-|开启录像||||
-|关闭录像||||
-|终端状态||||
-|单播消息|发送指定终端|||
-|广播消息|广播排除自己的所有终端|||
-|全员广播消息|广播包括自己的所有终端|||
-|异常|异常信息|||
-
## 直播
终端推流到服务端,由服务端分流。
## 会议
+Mesh架构声音视频控制部分功能均在终端实现,同时不会实现终端录制、美颜、AI识别、变声、混音等等功能。
+MCU/SFU声音视频控制在服务端实现,如果没有终端订阅并且没有录制是不会对终端进行拉流。
+
### Mesh
流媒体点对点连接,不经过服务端。
-> 录制、AI识别等等功能只能在终端实现。
-
### MCU
终端推流到服务端,由服务端分流并且混音。
diff --git a/docs/FFmpeg.md b/docs/FFmpeg.md
new file mode 100644
index 0000000..525add6
--- /dev/null
+++ b/docs/FFmpeg.md
@@ -0,0 +1,92 @@
+# FFmpeg
+
+默认使用`ffmpeg-platform`所以不用安装,如果使用本地FFmpeg需要自己安装。
+
+## FFmpeg
+
+```
+# nasm
+wget https://www.nasm.us/pub/nasm/releasebuilds/2.14/nasm-2.14.tar.gz
+tar zxvf nasm-2.14.tar.gz
+cd nasm-2.14
+./configure --prefix=/usr/local/nasm
+make -j && make install
+# 环境变量
+vim /etc/profile
+export PATH=$PATH:/usr/local/nasm/bin
+source /etc/profile
+
+# yasm
+wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
+tar zxvf yasm-1.3.0.tar.gz
+cd yasm-1.3.0
+./configure --prefix=/usr/local/yasm
+make -j && make install
+# 环境变量
+vim /etc/profile
+export PATH=$PATH:/usr/local/yasm/bin
+source /etc/profile
+
+# x264
+git clone https://code.videolan.org/videolan/x264.git
+cd x264
+./configure --prefix=/usr/local/x264 --libdir=/usr/local/lib --includedir=/usr/local/include --enable-shared --enable-static
+make -j && make install
+# 环境变量
+vim /etc/profile
+export PATH=$PATH:/usr/local/x264/bin
+source /etc/profile
+
+# 编码解码
+# acc
+https://github.com/mstorsjo/fdk-aac.git
+--enable-libfdk_aac
+# vpx
+https://github.com/webmproject/libvpx.git
+--enable-libvpx
+# x265
+https://bitbucket.org/multicoreware/x265
+--enable-libx265
+# opus
+https://archive.mozilla.org/pub/opus/opus-1.2.1.tar.gz
+--enable-libopus
+
+# ffmpeg
+wget http://www.ffmpeg.org/releases/ffmpeg-4.3.1.tar.xz
+tar xvJf ffmpeg-4.3.1.tar.xz
+cd ffmpeg-4.3.1
+./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-shared --enable-libx264
+# --enable-cuda --enable-cuvid --enable-nvenc --nvcc=/usr/local/cuda-11.0/bin/nvcc
+make -j && make install
+# 环境变量
+vim /etc/profile
+export PATH=$PATH:/usr/local/ffmpeg/bin
+source /etc/profile
+
+# lib
+vim /etc/ld.so.conf
+/usr/local/x264/lib/
+/usr/local/ffmpeg/lib/
+ldconfig
+
+# 查看版本
+ffmpeg -version
+# 查看编解码
+ffmpeg -codecs
+# 格式化文件
+ffmpeg -y -i source.mkv -c copy target.mp4
+# 查看文件格式
+ffprobe -v error -show_streams -print_format json source.mp4
+```
+
+## GPU
+
+```
+驱动
+# cuda
+https://developer.nvidia.com/cuda-downloads
+# nv-codec-headers
+https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
+# 验证
+nvidia-smi
+```
diff --git a/docs/LINK.md b/docs/LINK.md
new file mode 100644
index 0000000..ba1f7e3
--- /dev/null
+++ b/docs/LINK.md
@@ -0,0 +1,12 @@
+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/pom.xml b/pom.xml
index ff411f5..f3da863 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,8 @@
17
1.18.24
+ 1.5.8
+ 5.1.2
6.18.0
1.6.12
1.5.3.Final
@@ -61,7 +63,7 @@
org.projectlombok
lombok
-
+
org.apache.commons
commons-lang3
@@ -70,6 +72,11 @@
org.apache.commons
commons-collections4
+
+
+ org.springdoc
+ springdoc-openapi-ui
+
com.fasterxml.jackson.core
@@ -186,12 +193,62 @@
kurento-client
${kurento.version}
+
+
+ org.bytedeco
+ ffmpeg-platform
+ ${ffmpeg.version}-${javacv.version}
+
+
+ org.bytedeco
+ ffmpeg
+
+
+ org.bytedeco
+ javacpp
+
+
+
+
+ org.bytedeco
+ ffmpeg
+ ${ffmpeg.version}-${javacv.version}
+ ${javacv.os.version}
+
+
+ org.bytedeco
+ javacpp
+ ${javacv.version}
+ ${javacv.os.version}
+
org.apache.commons
commons-collections4
${collections4.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
org.mapstruct
@@ -205,13 +262,6 @@
${mapstruct.version}
provided
-
-
- org.projectlombok
- lombok
- ${lombok.version}
- provided
-
@@ -306,6 +356,7 @@
dev
+ windows-x86_64
-Xms512M -Xmx1024M -XX:NewRatio=1 -XX:SurvivorRatio=2
@@ -336,6 +387,7 @@
test
test
+ linux-x86_64
-Xms512M -Xmx1024M -XX:NewRatio=1 -XX:SurvivorRatio=2
@@ -367,7 +419,8 @@
release
release
- -Dtaoyao.password=123456
+ linux-x86_64
+
-Xms2048M -Xmx4096M -XX:NewRatio=1 -XX:SurvivorRatio=2
diff --git a/taoyao-boot/pom.xml b/taoyao-boot/pom.xml
index c9fa638..a1db1e0 100644
--- a/taoyao-boot/pom.xml
+++ b/taoyao-boot/pom.xml
@@ -14,16 +14,9 @@
jar
taoyao-boot
- 基础:启动模型
+ 启动模块:启动模块
-
-
- org.springdoc
- springdoc-openapi-ui
- true
-
-
org.springframework.boot
spring-boot-starter-web
diff --git a/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/SecurityProperties.java b/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/SecurityProperties.java
index 31b18c3..2469d0a 100644
--- a/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/SecurityProperties.java
+++ b/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/SecurityProperties.java
@@ -20,6 +20,10 @@ public class SecurityProperties {
*/
public static final String BASIC = "Basic";
+ /**
+ * 是否启用
+ */
+ private Boolean enabled;
/**
* 范围
*/
diff --git a/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/TaoyaoProperties.java b/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/TaoyaoProperties.java
index 391274b..ac02337 100644
--- a/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/TaoyaoProperties.java
+++ b/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/TaoyaoProperties.java
@@ -6,7 +6,7 @@ import lombok.Getter;
import lombok.Setter;
/**
- * 系统配置
+ * 平台配置
*
* @author acgist
*/
diff --git a/taoyao-boot/src/main/java/com/acgist/taoyao/boot/model/Message.java b/taoyao-boot/src/main/java/com/acgist/taoyao/boot/model/Message.java
index a46ce7a..2060776 100644
--- a/taoyao-boot/src/main/java/com/acgist/taoyao/boot/model/Message.java
+++ b/taoyao-boot/src/main/java/com/acgist/taoyao/boot/model/Message.java
@@ -24,7 +24,7 @@ import lombok.Setter;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class Message implements Serializable {
+public class Message implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
@@ -61,8 +61,8 @@ public class Message implements Serializable {
}
/**
- * @param code 状态编码
- * @param message
+ * @param code 响应编码
+ * @param message 响应描述
*
* @return this
*/
@@ -161,6 +161,30 @@ public class Message implements Serializable {
return failMessage;
}
+ @Override
+ public Message clone() {
+ try {
+ return (Message) super.clone();
+ } catch (CloneNotSupportedException e) {
+ return new Message(this.code, this.message, this.header, this.body);
+ }
+ }
+
+ /**
+ * 克隆排除主体
+ *
+ * @return 请求响应消息
+ */
+ public Message cloneWidthoutBody() {
+ try {
+ final Message message = (Message) super.clone();
+ message.setBody(null);
+ return message;
+ } catch (CloneNotSupportedException e) {
+ return new Message(this.code, this.message, this.header, null);
+ }
+ }
+
@Override
public String toString() {
return JSONUtils.toJSON(this);
diff --git a/taoyao-live/pom.xml b/taoyao-live/pom.xml
index dba5e74..2fc05eb 100644
--- a/taoyao-live/pom.xml
+++ b/taoyao-live/pom.xml
@@ -19,7 +19,7 @@
com.acgist
- taoyao-signal
+ taoyao-media
diff --git a/taoyao-live/src/main/java/com/acgist/taoyao/live/Live.java b/taoyao-live/src/main/java/com/acgist/taoyao/live/Live.java
new file mode 100644
index 0000000..e0119f5
--- /dev/null
+++ b/taoyao-live/src/main/java/com/acgist/taoyao/live/Live.java
@@ -0,0 +1,17 @@
+package com.acgist.taoyao.live;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 直播
+ *
+ * @author acgist
+ */
+@Getter
+@Setter
+@Schema(title = "直播", description = "直播")
+public class Live {
+
+}
diff --git a/taoyao-live/src/main/java/com/acgist/taoyao/live/LiveManager.java b/taoyao-live/src/main/java/com/acgist/taoyao/live/LiveManager.java
new file mode 100644
index 0000000..9433055
--- /dev/null
+++ b/taoyao-live/src/main/java/com/acgist/taoyao/live/LiveManager.java
@@ -0,0 +1,5 @@
+package com.acgist.taoyao.live;
+
+public class LiveManager {
+
+}
diff --git a/taoyao-live/src/main/java/com/acgist/taoyao/live/controller/LiveController.java b/taoyao-live/src/main/java/com/acgist/taoyao/live/controller/LiveController.java
new file mode 100644
index 0000000..10d95cd
--- /dev/null
+++ b/taoyao-live/src/main/java/com/acgist/taoyao/live/controller/LiveController.java
@@ -0,0 +1,33 @@
+package com.acgist.taoyao.live.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.live.Live;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+/**
+ * 直播
+ *
+ * @author acgist
+ */
+@Tag(name = "直播", description = "直播管理")
+@RestController
+@RequestMapping("/live")
+public class LiveController {
+
+ @Operation(summary = "直播列表", description = "直播列表")
+ @GetMapping("/list")
+ @ApiResponse(content = @Content(schema = @Schema(implementation = Live.class)))
+ public Message list() {
+ return Message.success();
+ }
+
+}
diff --git a/taoyao-media/README.md b/taoyao-media/README.md
new file mode 100644
index 0000000..0cece0c
--- /dev/null
+++ b/taoyao-media/README.md
@@ -0,0 +1 @@
+# 媒体
diff --git a/taoyao-media/pom.xml b/taoyao-media/pom.xml
index 0445f84..b077856 100644
--- a/taoyao-media/pom.xml
+++ b/taoyao-media/pom.xml
@@ -37,6 +37,20 @@
com.acgist
taoyao-webrtc-kurento
+
+ org.bytedeco
+ ffmpeg-platform
+
+
+ org.bytedeco
+ ffmpeg
+ ${javacv.os.version}
+
+
+ org.bytedeco
+ javacpp
+ ${javacv.os.version}
+
\ No newline at end of file
diff --git a/taoyao-media/src/main/java/com/acgist/taoyao/media/process/AggregateProcessor.java b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/AggregateProcessor.java
new file mode 100644
index 0000000..45a2b6f
--- /dev/null
+++ b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/AggregateProcessor.java
@@ -0,0 +1,10 @@
+package com.acgist.taoyao.media.process;
+
+/**
+ * 责任链模式
+ *
+ * @author acgist
+ */
+public class AggregateProcessor {
+
+}
diff --git a/taoyao-media/src/main/java/com/acgist/taoyao/media/process/Processor.java b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/Processor.java
new file mode 100644
index 0000000..49cf274
--- /dev/null
+++ b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/Processor.java
@@ -0,0 +1,5 @@
+package com.acgist.taoyao.media.process;
+
+public class Processor {
+
+}
diff --git a/taoyao-media/src/main/java/com/acgist/taoyao/media/process/ProcessorChain.java b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/ProcessorChain.java
new file mode 100644
index 0000000..3fbc6df
--- /dev/null
+++ b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/ProcessorChain.java
@@ -0,0 +1,5 @@
+package com.acgist.taoyao.media.process;
+
+public class ProcessorChain {
+
+}
diff --git a/taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/DenoiseProcessor.java b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/DenoiseProcessor.java
new file mode 100644
index 0000000..1e4e628
--- /dev/null
+++ b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/DenoiseProcessor.java
@@ -0,0 +1,10 @@
+package com.acgist.taoyao.media.process.audio;
+
+/**
+ * 降噪
+ *
+ * @author acgist
+ */
+public class DenoiseProcessor {
+
+}
diff --git a/taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/MixProcessor.java b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/MixProcessor.java
new file mode 100644
index 0000000..1234729
--- /dev/null
+++ b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/MixProcessor.java
@@ -0,0 +1,10 @@
+package com.acgist.taoyao.media.process.audio;
+
+/**
+ * 混音
+ *
+ * @author acgist
+ */
+public class MixProcessor {
+
+}
diff --git a/taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/WhineProcessor.java b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/WhineProcessor.java
new file mode 100644
index 0000000..466282d
--- /dev/null
+++ b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/audio/WhineProcessor.java
@@ -0,0 +1,10 @@
+package com.acgist.taoyao.media.process.audio;
+
+/**
+ * 变声器
+ *
+ * @author acgist
+ */
+public class WhineProcessor {
+
+}
diff --git a/taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/BeautyHandler.java b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/BeautyHandler.java
new file mode 100644
index 0000000..670d8f1
--- /dev/null
+++ b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/BeautyHandler.java
@@ -0,0 +1,10 @@
+package com.acgist.taoyao.media.process.video;
+
+/**
+ * 美颜
+ *
+ * @author acgist
+ */
+public class BeautyHandler {
+
+}
diff --git a/taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/MarkHandler.java b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/MarkHandler.java
new file mode 100644
index 0000000..0812121
--- /dev/null
+++ b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/MarkHandler.java
@@ -0,0 +1,10 @@
+package com.acgist.taoyao.media.process.video;
+
+/**
+ * AI识别
+ *
+ * @author acgist
+ */
+public class MarkHandler {
+
+}
diff --git a/taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/WatermarkHandler.java b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/WatermarkHandler.java
new file mode 100644
index 0000000..c6914b1
--- /dev/null
+++ b/taoyao-media/src/main/java/com/acgist/taoyao/media/process/video/WatermarkHandler.java
@@ -0,0 +1,10 @@
+package com.acgist.taoyao.media.process.video;
+
+/**
+ * 水印
+ *
+ * @author acgist
+ */
+public class WatermarkHandler {
+
+}
diff --git a/taoyao-meeting/pom.xml b/taoyao-meeting/pom.xml
index 289a424..d59724d 100644
--- a/taoyao-meeting/pom.xml
+++ b/taoyao-meeting/pom.xml
@@ -19,7 +19,7 @@
com.acgist
- taoyao-signal
+ taoyao-media
diff --git a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java
new file mode 100644
index 0000000..a4c5d53
--- /dev/null
+++ b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java
@@ -0,0 +1,17 @@
+package com.acgist.taoyao.meeting;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 会议
+ *
+ * @author acgist
+ */
+@Getter
+@Setter
+@Schema(title = "会议", description = "会议")
+public class Meeting {
+
+}
diff --git a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java
new file mode 100644
index 0000000..acd40bc
--- /dev/null
+++ b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java
@@ -0,0 +1,10 @@
+package com.acgist.taoyao.meeting;
+
+/**
+ * 房间
+ *
+ * @author acgist
+ */
+public class MeetingManager {
+
+}
diff --git a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/controller/MeetingController.java b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/controller/MeetingController.java
new file mode 100644
index 0000000..e1f3baf
--- /dev/null
+++ b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/controller/MeetingController.java
@@ -0,0 +1,33 @@
+package com.acgist.taoyao.meeting.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.meeting.Meeting;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+/**
+ * 会议
+ *
+ * @author acgist
+ */
+@Tag(name = "会议", description = "会议管理")
+@RestController
+@RequestMapping("/meeting")
+public class MeetingController {
+
+ @Operation(summary = "会议列表", description = "会议列表")
+ @GetMapping("/list")
+ @ApiResponse(content = @Content(schema = @Schema(implementation = Meeting.class)))
+ public Message list() {
+ return Message.success();
+ }
+
+}
diff --git a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/room/Room.java b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/room/Room.java
deleted file mode 100644
index 0dcf674..0000000
--- a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/room/Room.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.acgist.taoyao.meeting.room;
-
-/**
- * 房间
- *
- * @author acgist
- */
-public class Room {
-
-}
diff --git a/taoyao-server/pom.xml b/taoyao-server/pom.xml
index 93f78b1..c508c24 100644
--- a/taoyao-server/pom.xml
+++ b/taoyao-server/pom.xml
@@ -14,7 +14,7 @@
jar
taoyao-server
- 服务:启动服务
+ 启动服务:启动服务
${project.parent.basedir}
@@ -26,18 +26,10 @@
com.acgist
taoyao-live
-
- com.acgist
- taoyao-signal
-
com.acgist
taoyao-meeting
-
- org.springdoc
- springdoc-openapi-ui
-
com.acgist
diff --git a/taoyao-server/src/main/java/com/acgist/taoyao/config/TaoyaoAutoConfiguration.java b/taoyao-server/src/main/java/com/acgist/taoyao/config/TaoyaoAutoConfiguration.java
index 059fa63..5321970 100644
--- a/taoyao-server/src/main/java/com/acgist/taoyao/config/TaoyaoAutoConfiguration.java
+++ b/taoyao-server/src/main/java/com/acgist/taoyao/config/TaoyaoAutoConfiguration.java
@@ -1,6 +1,7 @@
package com.acgist.taoyao.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -22,6 +23,7 @@ public class TaoyaoAutoConfiguration {
}
@Bean
+ @ConditionalOnProperty(prefix = "taoyao.security", name = "enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnMissingBean
public SecurityInterceptor securityInterceptor() {
return new SecurityInterceptor();
diff --git a/taoyao-server/src/main/java/com/acgist/taoyao/controller/ConfigController.java b/taoyao-server/src/main/java/com/acgist/taoyao/controller/ConfigController.java
index d965f0c..0aeea3c 100644
--- a/taoyao-server/src/main/java/com/acgist/taoyao/controller/ConfigController.java
+++ b/taoyao-server/src/main/java/com/acgist/taoyao/controller/ConfigController.java
@@ -7,8 +7,12 @@ import org.springframework.web.bind.annotation.RestController;
import com.acgist.taoyao.boot.config.MediaProperties;
import com.acgist.taoyao.boot.config.WebrtcProperties;
+import com.acgist.taoyao.boot.model.Message;
import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
/**
@@ -28,14 +32,16 @@ public class ConfigController {
@Operation(summary = "媒体配置", description = "媒体配置")
@GetMapping("/media")
- public MediaProperties media() {
- return this.mediaProperties;
+ @ApiResponse(content = @Content(schema = @Schema(implementation = MediaProperties.class)))
+ public Message media() {
+ return Message.success(this.mediaProperties);
}
@Operation(summary = "WebRTC配置", description = "WebRTC配置")
@GetMapping("/webrtc")
- public WebrtcProperties webrtc() {
- return this.webrtcProperties;
+ @ApiResponse(content = @Content(schema = @Schema(implementation = WebrtcProperties.class)))
+ public Message webrtc() {
+ return Message.success(this.webrtcProperties);
}
}
diff --git a/taoyao-server/src/main/resources/application.yml b/taoyao-server/src/main/resources/application.yml
index 583fdc5..3948293 100644
--- a/taoyao-server/src/main/resources/application.yml
+++ b/taoyao-server/src/main/resources/application.yml
@@ -81,6 +81,7 @@ taoyao:
record:
storage: /data/record
security:
+ enabled: true
realm: taoyao
permit: /v3/api-docs/,/swagger-ui/,/favicon.ico,/error
username: taoyao
diff --git a/taoyao-server/src/main/resources/static/javascript/taoyao.js b/taoyao-server/src/main/resources/static/javascript/taoyao.js
index fcee481..05bc143 100644
--- a/taoyao-server/src/main/resources/static/javascript/taoyao.js
+++ b/taoyao-server/src/main/resources/static/javascript/taoyao.js
@@ -1,6 +1,6 @@
/** 桃夭WebRTC终端核心功能 */
/** 配置 */
-const config = {
+const taoyaoConfig = {
// 当前终端SN
sn: 'taoyao',
// 信令授权
@@ -86,24 +86,26 @@ function Taoyao(
let audioDevice = false;
let videoDevice = false;
list.forEach(v => {
- console.log('终端媒体设备', v.kind, v.label);
+ console.debug('终端媒体设备', v.kind, v.label);
if(v.kind === 'audioinput') {
audioDevice = true;
} else if(v.kind === 'videoinput') {
videoDevice = true;
+ } else {
+ console.debug('没有适配设备', v.kind, v.label);
}
});
if(!audioDevice) {
- console.log('终端没有音频输入设备');
+ console.warn('终端没有音频输入设备');
self.audioEnabled = false;
}
if(!videoDevice) {
- console.log('终端没有视频输入设备');
+ console.warn('终端没有视频输入设备');
self.videoEnabled = false;
}
})
.catch(e => {
- console.log('获取终端设备失败', e);
+ console.error('获取终端设备失败', e);
self.videoEnabled = false;
self.videoEnabled = false;
});
@@ -120,19 +122,31 @@ function Taoyao(
xhr.responseType = mime;
xhr.send(data);
xhr.onload = function() {
+ let response = xhr.response;
if(xhr.readyState === 4 && xhr.status === 200) {
- resolve(xhr.response);
+ if(response.code === '0000') {
+ resolve(response.body);
+ } else {
+ reject(response.body || response);
+ }
} else {
- reject(xhr.response);
+ 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(JSON.parse(xhr.response));
+ resolve(response.body || response);
} else {
- reject(JSON.parse(xhr.response));
+ reject(response.body || response);
}
}
});
@@ -141,13 +155,13 @@ function Taoyao(
this.configMedia = function(audio = {}, video = {}) {
this.audioConfig = {...this.audioConfig, ...audio};
this.videoCofnig = {...this.videoCofnig, ...video};
- console.log('终端媒体配置', this.audioConfig, this.videoConfig);
+ console.debug('终端媒体配置', this.audioConfig, this.videoConfig);
};
/** WebRTC配置 */
this.configWebrtc = function(config = {}) {
this.webSocket = config.signalAddress;
this.iceServer = config.stun;
- console.log('WebRTC配置', this.webSocket, this.iceServer);
+ console.debug('WebRTC配置', this.webSocket, this.iceServer);
};
/** 信令通道 */
this.buildChannel = function(callback) {
@@ -160,7 +174,7 @@ function Taoyao(
};
/** 本地媒体 */
this.buildLocalMedia = function() {
- console.log("获取终端媒体:", 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,6 +204,14 @@ function Taoyao(
}
await this.localVideo.play();
};
+ /** 关闭:关闭媒体 */
+ this.close = function() {
+ // TODO:释放资源
+ };
+ /** 关机:关闭媒体、关闭信令 */
+ this.shutdown = function() {
+ this.close();
+ }
/** 媒体 */
/** 视频 */
};
@@ -197,7 +219,7 @@ function Taoyao(
const protocol = {
pid: {
/** 心跳 */
- heartbeat: 1000,
+ heartbeat: 2005,
/** 注册 */
register: 2000
},
@@ -240,7 +262,7 @@ const signalChannel = {
/** 回调事件 */
callbackMapping: new Map(),
/** 心跳时间 */
- heartbeatTime: 10 * 1000,
+ heartbeatTime: 30 * 1000,
/** 心跳定时器 */
heartbeatTimer: null,
/** 防止重连 */
@@ -250,9 +272,9 @@ const signalChannel = {
/** 最小重连时间 */
minReconnectionDelay: 5 * 1000,
/** 最大重连时间 */
- maxReconnectionDelay: 5 * 60 * 1000,
+ maxReconnectionDelay: 60 * 1000,
/** 自动重连失败后重连时间增长倍数 */
- reconnectionDelayGrowFactor: 1.5,
+ reconnectionDelayGrowFactor: 2,
/** 关闭 */
close: function() {
clearTimeout(this.heartbeatTimer);
@@ -262,10 +284,17 @@ const signalChannel = {
let self = this;
self.heartbeatTimer = setTimeout(function() {
if (self.channel && self.channel.readyState == WebSocket.OPEN) {
- self.push(protocol.buildProtocol(config.sn, protocol.pid.heartbeat));
+ self.push(protocol.buildProtocol(
+ taoyaoConfig.sn,
+ protocol.pid.heartbeat,
+ {
+ signal: 100,
+ battery: 100
+ }
+ ));
self.heartbeat();
} else {
- console.log('发送心跳失败', self.channel);
+ console.warn('发送心跳失败', self.channel);
}
}, self.heartbeatTime);
},
@@ -283,7 +312,7 @@ const signalChannel = {
}
// 打开定时重连
setTimeout(function() {
- console.log('信令通道重连', self.address);
+ console.info('信令通道重连', self.address);
self.connect(self.address, self.callback, true);
self.lockReconnect = false;
}, self.connectionTimeout);
@@ -298,21 +327,21 @@ const signalChannel = {
let self = this;
this.address = address;
this.callback = callback;
- console.log("连接信令通道", address);
+ console.debug("连接信令通道", address);
return new Promise((resolve, reject) => {
self.channel = new WebSocket(address);
self.channel.onopen = function(e) {
- console.log('信令通道打开', e);
+ console.debug('信令通道打开', e);
self.push(protocol.buildProtocol(
- config.sn,
+ taoyaoConfig.sn,
protocol.pid.register,
{
ip: null,
mac: null,
signal: 100,
battery: 100,
- username: config.username,
- password: config.password
+ username: taoyaoConfig.username,
+ password: taoyaoConfig.password
}
));
self.connectionTimeout = self.minReconnectionDelay
@@ -320,7 +349,7 @@ const signalChannel = {
resolve(e);
};
self.channel.onclose = function(e) {
- console.log('信令通道关闭', self.channel, e);
+ console.error('信令通道关闭', self.channel, e);
if(reconnection) {
self.reconnect();
}
@@ -334,17 +363,20 @@ const signalChannel = {
reject(e);
};
self.channel.onmessage = function(e) {
- console.log('信令消息', e.data);
+ console.debug('信令消息', e.data);
let data = JSON.parse(e.data);
// 注册回调
+ let done = false;
if(callback) {
- callback(data);
+ 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);
};
});
},
@@ -354,11 +386,22 @@ const signalChannel = {
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;
+ }
}
};
/*
diff --git a/taoyao-server/src/main/resources/static/meeting.html b/taoyao-server/src/main/resources/static/meeting.html
index 4d7ed53..e14d7ab 100644
--- a/taoyao-server/src/main/resources/static/meeting.html
+++ b/taoyao-server/src/main/resources/static/meeting.html
@@ -71,11 +71,12 @@
switch(data.header.pid) {
case protocol.pid.heartbeat:
// 心跳
- break;
+ return true;
case protocol.pid.register:
- // 录制
- break;
+ // 注册
+ return true;
}
+ return false;
}
// 创建房间
function create() {
@@ -91,7 +92,7 @@
}
// 录制视频
function record(e) {
- taoyao.push(protocol.buildProtocol(config.sn, protocol.pid.heartbeat), () => {
+ taoyao.push(protocol.buildProtocol(taoyaoConfig.sn, protocol.pid.heartbeat), () => {
classSwitch(e, 'active');
});
}
diff --git a/taoyao-server/src/test/java/com/acgist/taoyao/signal/protocol/ScriptProtocolTest.java b/taoyao-server/src/test/java/com/acgist/taoyao/signal/protocol/ScriptProtocolTest.java
new file mode 100644
index 0000000..7bd8d72
--- /dev/null
+++ b/taoyao-server/src/test/java/com/acgist/taoyao/signal/protocol/ScriptProtocolTest.java
@@ -0,0 +1,27 @@
+package com.acgist.taoyao.signal.protocol;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.acgist.taoyao.main.TaoyaoApplication;
+import com.acgist.taoyao.signal.protocol.platform.ScriptProtocol;
+import com.acgist.taoyao.test.annotation.TaoyaoTest;
+
+@TaoyaoTest(classes = TaoyaoApplication.class)
+class ScriptProtocolTest {
+
+ @Autowired
+ private ScriptProtocol scriptProtocol;
+
+ @Test
+ void testScript() {
+ assertDoesNotThrow(() -> {
+ this.scriptProtocol.execute(null, Map.of("script", "netstat -ano"), null, null);
+ });
+ }
+
+}
diff --git a/taoyao-server/src/test/java/com/acgist/taoyao/signal/protocol/ShutdownProtocolTest.java b/taoyao-server/src/test/java/com/acgist/taoyao/signal/protocol/ShutdownProtocolTest.java
new file mode 100644
index 0000000..a300ab6
--- /dev/null
+++ b/taoyao-server/src/test/java/com/acgist/taoyao/signal/protocol/ShutdownProtocolTest.java
@@ -0,0 +1,25 @@
+package com.acgist.taoyao.signal.protocol;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.acgist.taoyao.main.TaoyaoApplication;
+import com.acgist.taoyao.signal.protocol.platform.ShutdownProtocol;
+import com.acgist.taoyao.test.annotation.TaoyaoTest;
+
+@TaoyaoTest(classes = TaoyaoApplication.class)
+class ShutdownProtocolTest {
+
+ @Autowired
+ private ShutdownProtocol shutdownProtocol;
+
+ @Test
+ void testShutdown() {
+ assertDoesNotThrow(() -> {
+ this.shutdownProtocol.execute("taoyao", null, null);
+ });
+ }
+
+}
diff --git a/taoyao-signal/README.md b/taoyao-signal/README.md
index 9519294..35cef2d 100644
--- a/taoyao-signal/README.md
+++ b/taoyao-signal/README.md
@@ -1,6 +1,6 @@
# 信令
-## 格式
+## 信令
```
{
@@ -13,37 +13,179 @@
"code": "响应编码",
"message": "响应描述",
"body": {
- // 信令参数
+ // 信令主体
}
}
```
-## 系统信令(1000~1999|9999)
+## 平台信令(1000~1999)
-### 心跳信令(1000)
+### 关闭服务信令(1000)
+
+关闭信令服务
```
{}
```
-### 异常信令(9999)
+### 执行命令信令(1001)
-## 设备信令(2000~2999)
-
-### 注册信令(2000)
+执行系统命令
```
{
-"username": "username",
-"password": "password"
+ "script": "命令"
+}
+```
+
+### 异常信令(1999)
+
+```
+{}
+```
+
+## 终端信令(2000~2999)
+
+### 注册信令(2000)
+
+终端注册:响应、广播上线通知
+
+```
+{
+ "username": "信令授权用户",
+ "password": "信令授权密码",
+ "ip": "IP地址",
+ "mac": "MAC地址",
+ "signal": "信号强度",
+ "battery": "电池电量"
}
```
### 关闭信令(2001)
+关闭终端(注销):广播下线通知、释放所有连接
+
+```
+{}
+```
+
### 上线信令(2002)
+通知终端上线
+
+```
+{
+ "sn": "终端标识"
+}
+```
+
### 下线信令(2003)
-## 房间信令(3000~3999)
+通知终端下线
+```
+{
+ "sn": "终端标识"
+}
+```
+
+### 下发配置信令(2004)
+
+### 心跳信令(2005)
+
+心跳:响应
+
+```
+{
+ "signal": "信号强度",
+ "battery": "电池电量"
+}
+```
+
+### 终端列表信令(2006)
+
+返回所有终端状态列表
+
+```
+{}
+```
+
+### 终端状态信令(2007)
+
+返回指定终端状态(如果没有指定终端标识默认查询自己)
+
+```
+{
+ "sn": "终端标识"
+}
+```
+
+### 单播信令(2008)
+
+发送到指定的终端:删除`to`字段
+
+```
+{
+ "to": "接收终端标识",
+ // 主体信息
+}
+```
+
+### 广播信令(2009)
+
+发送到所有的终端:排除自己
+
+```
+{
+ // 主体信息
+}
+```
+
+## 直播信令(3000~3999)
+
+```
+创建会议 -> 邀请终端|踢出终端|加入会议|离开会议 -> 光比会议
+```
+
+### 开启直播信令(3000)
+
+### 关闭直播信令(3001)
+
+### 直播终端列表信令(3002)
+
+## 会议信令(4000~4999)
+
+### 创建会议信令(4000)
+
+### 关闭会议信令(4001)
+
+释放资源、广播广播
+
+### 进入会议信令(4002)
+
+广播
+
+### 离开会议信令(4003)
+
+广播
+
+### 邀请终端信令(4004)
+
+邀请终端进入会议,终端确认进入发送进入会议信令。
+
+### 踢出终端信令(4005)
+
+广播
+
+### 会议终端列表信令(4006)
+
+## 媒体信令(5000~5999)
+
+|发布|控制终端推流(服务端拉流)|||
+|取消发布|控制终端暂停推流(服务端取消拉流)|||
+|订阅|订阅终端媒体流(终端拉流)|||
+|取消订阅|取消订阅终端媒体流(终端取消拉流)|||
+|暂停媒体流|暂停终端媒体流分流(不关媒体流通道)|||
+|恢复媒体流|恢复终端媒体流分流(不关媒体流通道)|||
+|开启录像||||
+|关闭录像||||
\ No newline at end of file
diff --git a/taoyao-signal/pom.xml b/taoyao-signal/pom.xml
index 5965627..49d3adb 100644
--- a/taoyao-signal/pom.xml
+++ b/taoyao-signal/pom.xml
@@ -19,7 +19,7 @@
com.acgist
- taoyao-media
+ taoyao-boot
org.springframework.boot
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSession.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSession.java
similarity index 95%
rename from taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSession.java
rename to taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSession.java
index 915185d..faecb9a 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSession.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSession.java
@@ -1,11 +1,11 @@
-package com.acgist.taoyao.signal.session;
+package com.acgist.taoyao.signal.client;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.signal.media.ClientMediaPublisher;
import com.acgist.taoyao.signal.media.ClientMediaSubscriber;
/**
- * 会话
+ * 终端会话
*
* @author acgist
*
@@ -17,7 +17,7 @@ public interface ClientSession extends AutoCloseable {
* @return 终端标识
*/
String sn();
-
+
/**
* @return 终端状态
*/
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSessionAdapter.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSessionAdapter.java
similarity index 93%
rename from taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSessionAdapter.java
rename to taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSessionAdapter.java
index 5c66432..fa485c4 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSessionAdapter.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSessionAdapter.java
@@ -1,4 +1,4 @@
-package com.acgist.taoyao.signal.session;
+package com.acgist.taoyao.signal.client;
import org.apache.commons.lang3.StringUtils;
@@ -103,12 +103,7 @@ public abstract class ClientSessionAdapter implements C
@Override
public void close() throws Exception {
- try {
- this.instance.close();
- } finally {
- // TODO:退出房间
- // TODO:退出帐号
- }
+ this.instance.close();
}
/**
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSessionManager.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSessionManager.java
similarity index 74%
rename from taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSessionManager.java
rename to taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSessionManager.java
index fc103f9..9916d25 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSessionManager.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSessionManager.java
@@ -1,14 +1,17 @@
-package com.acgist.taoyao.signal.session;
+package com.acgist.taoyao.signal.client;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.acgist.taoyao.boot.config.TaoyaoProperties;
import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.event.client.CloseEvent;
import lombok.extern.slf4j.Slf4j;
@@ -21,6 +24,8 @@ import lombok.extern.slf4j.Slf4j;
@Service
public class ClientSessionManager {
+ @Autowired
+ private ApplicationContext context;
@Autowired
private TaoyaoProperties taoyaoProperties;
@@ -91,6 +96,32 @@ public class ClientSessionManager {
});
}
+ /**
+ * @param sn 终端标识
+ *
+ * @return 终端会话
+ */
+ public ClientSession session(String sn) {
+ return this.sessions.stream()
+ .filter(v -> StringUtils.equals(sn, v.sn()))
+ .findFirst()
+ .orElse(null);
+ }
+
+ /**
+ * @return 所有终端会话
+ */
+ public List sessions() {
+ return this.sessions;
+ }
+
+ /**
+ * @return 所有终端状态
+ */
+ public List status() {
+ return this.sessions().stream().map(ClientSession::status).toList();
+ }
+
/**
* 关闭会话
*
@@ -101,13 +132,17 @@ public class ClientSessionManager {
try {
if(session != null) {
session.close();
+ } else {
+ instance.close();
}
- instance.close();
} catch (Exception e) {
log.error("关闭会话异常", e);
} finally {
if(session != null) {
+ // 移除管理
this.sessions.remove(session);
+ // 关闭事件
+ this.context.publishEvent(new CloseEvent(null, session));
}
}
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSessionStatus.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSessionStatus.java
similarity index 90%
rename from taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSessionStatus.java
rename to taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSessionStatus.java
index 8740e01..8a35ea3 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/ClientSessionStatus.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientSessionStatus.java
@@ -1,4 +1,4 @@
-package com.acgist.taoyao.signal.session;
+package com.acgist.taoyao.signal.client;
import lombok.Getter;
import lombok.Setter;
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/socket/SocketSession.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/socket/SocketSession.java
similarity index 84%
rename from taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/socket/SocketSession.java
rename to taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/socket/SocketSession.java
index 046402d..5ade63f 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/socket/SocketSession.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/socket/SocketSession.java
@@ -1,10 +1,10 @@
-package com.acgist.taoyao.signal.session.socket;
+package com.acgist.taoyao.signal.client.socket;
import java.io.IOException;
import java.net.Socket;
import com.acgist.taoyao.boot.model.Message;
-import com.acgist.taoyao.signal.session.ClientSessionAdapter;
+import com.acgist.taoyao.signal.client.ClientSessionAdapter;
import lombok.Getter;
import lombok.Setter;
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/socket/SocketSignal.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/socket/SocketSignal.java
similarity index 61%
rename from taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/socket/SocketSignal.java
rename to taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/socket/SocketSignal.java
index 02f40d2..10e638a 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/socket/SocketSignal.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/socket/SocketSignal.java
@@ -1,4 +1,4 @@
-package com.acgist.taoyao.signal.session.socket;
+package com.acgist.taoyao.signal.client.socket;
/**
* Socket信令
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/websocket/WebSocketSession.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/websocket/WebSocketSession.java
similarity index 85%
rename from taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/websocket/WebSocketSession.java
rename to taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/websocket/WebSocketSession.java
index 7dd2ddf..adbcb00 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/websocket/WebSocketSession.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/websocket/WebSocketSession.java
@@ -1,9 +1,9 @@
-package com.acgist.taoyao.signal.session.websocket;
+package com.acgist.taoyao.signal.client.websocket;
import javax.websocket.Session;
import com.acgist.taoyao.boot.model.Message;
-import com.acgist.taoyao.signal.session.ClientSessionAdapter;
+import com.acgist.taoyao.signal.client.ClientSessionAdapter;
import lombok.Getter;
import lombok.Setter;
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/websocket/WebSocketSignal.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/websocket/WebSocketSignal.java
similarity index 93%
rename from taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/websocket/WebSocketSignal.java
rename to taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/websocket/WebSocketSignal.java
index 81b8f9a..edff458 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/session/websocket/WebSocketSignal.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/websocket/WebSocketSignal.java
@@ -1,4 +1,4 @@
-package com.acgist.taoyao.signal.session.websocket;
+package com.acgist.taoyao.signal.client.websocket;
import javax.websocket.OnClose;
import javax.websocket.OnError;
@@ -10,9 +10,9 @@ import javax.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSessionManager;
import com.acgist.taoyao.signal.protocol.ProtocolManager;
-import com.acgist.taoyao.signal.protocol.system.ErrorProtocol;
-import com.acgist.taoyao.signal.session.ClientSessionManager;
+import com.acgist.taoyao.signal.protocol.platform.ErrorProtocol;
import lombok.extern.slf4j.Slf4j;
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/config/SignalAutoConfiguration.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/config/SignalAutoConfiguration.java
index 24bfb65..cf9b19a 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/config/SignalAutoConfiguration.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/config/SignalAutoConfiguration.java
@@ -6,7 +6,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
-import com.acgist.taoyao.signal.session.websocket.WebSocketSignal;
+import com.acgist.taoyao.signal.client.websocket.WebSocketSignal;
/**
* 信令配置
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java
new file mode 100644
index 0000000..609867c
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java
@@ -0,0 +1,33 @@
+package com.acgist.taoyao.signal.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSessionManager;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+/**
+ * 终端
+ *
+ * @author acgist
+ */
+@Tag(name = "终端", description = "终端管理")
+@RestController
+@RequestMapping("/client")
+public class ClientController {
+
+ @Autowired
+ private ClientSessionManager clientSessionManager;
+
+ @Operation(summary = "终端列表", description = "终端列表")
+ @GetMapping("/list")
+ public Message list() {
+ return Message.success(this.clientSessionManager.status());
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/ApplicationEventAdapter.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/ApplicationEventAdapter.java
new file mode 100644
index 0000000..390b681
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/ApplicationEventAdapter.java
@@ -0,0 +1,48 @@
+package com.acgist.taoyao.signal.event;
+
+import java.util.Map;
+
+import org.springframework.context.ApplicationEvent;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 事件适配器
+ *
+ * @author acgist
+ */
+@Getter
+@Setter
+public abstract class ApplicationEventAdapter extends ApplicationEvent {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主体
+ */
+ private final Map, ?> body;
+ /**
+ * 消息
+ */
+ private final Message message;
+ /**
+ * 会话
+ */
+ private final ClientSession session;
+
+ public ApplicationEventAdapter(Message message, ClientSession session) {
+ this(null, message, session);
+ }
+
+ public ApplicationEventAdapter(Map, ?> body, Message message, ClientSession session) {
+ super(session);
+ this.body = body;
+ this.message = message;
+ this.session = session;
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/CloseEvent.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/CloseEvent.java
new file mode 100644
index 0000000..6626361
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/CloseEvent.java
@@ -0,0 +1,25 @@
+package com.acgist.taoyao.signal.event.client;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.event.ApplicationEventAdapter;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 关闭事件
+ *
+ * @author acgist
+ */
+@Getter
+@Setter
+public class CloseEvent extends ApplicationEventAdapter {
+
+ private static final long serialVersionUID = 1L;
+
+ public CloseEvent(Message message, ClientSession session) {
+ super(message, session);
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/RegisterEvent.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/RegisterEvent.java
index e3abd2f..2ee7136 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/RegisterEvent.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/RegisterEvent.java
@@ -2,37 +2,26 @@ package com.acgist.taoyao.signal.event.client;
import java.util.Map;
-import org.springframework.context.ApplicationEvent;
-
-import com.acgist.taoyao.signal.session.ClientSession;
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.event.ApplicationEventAdapter;
import lombok.Getter;
import lombok.Setter;
/**
- * 终端注册事件
+ * 注册事件
*
* @author acgist
*/
@Getter
@Setter
-public class RegisterEvent extends ApplicationEvent {
-
+public class RegisterEvent extends ApplicationEventAdapter {
+
private static final long serialVersionUID = 1L;
-
- /**
- * 会话
- */
- private ClientSession session;
- /**
- * 参数
- */
- private Map, ?> data;
-
- public RegisterEvent(ClientSession session, Map, ?> data) {
- super(session);
- this.session = session;
- this.data = data;
+
+ public RegisterEvent(Map, ?> body, Message message, ClientSession session) {
+ super(body, message, session);
}
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/ScriptEvent.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/ScriptEvent.java
new file mode 100644
index 0000000..0c5f448
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/ScriptEvent.java
@@ -0,0 +1,22 @@
+package com.acgist.taoyao.signal.event.platform;
+
+import java.util.Map;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.event.ApplicationEventAdapter;
+
+/**
+ * 执行命令事件
+ *
+ * @author acgist
+ */
+public class ScriptEvent extends ApplicationEventAdapter {
+
+ private static final long serialVersionUID = 1L;
+
+ public ScriptEvent(Map, ?> body, Message message, ClientSession session) {
+ super(body, message, session);
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/ApplicationListenerAdapter.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/ApplicationListenerAdapter.java
index fc5002f..6537c64 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/ApplicationListenerAdapter.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/ApplicationListenerAdapter.java
@@ -1,19 +1,19 @@
package com.acgist.taoyao.signal.listener;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
-import com.acgist.taoyao.signal.session.ClientSessionManager;
+import com.acgist.taoyao.signal.client.ClientSessionManager;
+import com.acgist.taoyao.signal.event.ApplicationEventAdapter;
/**
- * 事件监听
+ * 事件监听适配器
*
* @param 事件泛型
*
* @author acgist
*/
-public abstract class ApplicationListenerAdapter implements ApplicationListener {
+public abstract class ApplicationListenerAdapter implements ApplicationListener {
@Autowired
protected ClientSessionManager clientSessionManager;
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/CloseListener.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/CloseListener.java
new file mode 100644
index 0000000..f8311f8
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/CloseListener.java
@@ -0,0 +1,50 @@
+package com.acgist.taoyao.signal.listener.client;
+
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.event.client.CloseEvent;
+import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter;
+import com.acgist.taoyao.signal.protocol.client.OfflineProtocol;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 关闭监听
+ *
+ * @author acgist
+ */
+@Slf4j
+@Component
+public class CloseListener extends ApplicationListenerAdapter {
+
+ @Autowired
+ private OfflineProtocol offlineProtocol;
+
+ @Override
+ public void onApplicationEvent(CloseEvent event) {
+ final ClientSession session = event.getSession();
+ final String sn = session.sn();
+ if(StringUtils.isEmpty(sn)) {
+ // 没有授权终端
+ return;
+ }
+ log.info("关闭终端:{}", sn);
+ // 广播下线事件
+ final Message message = this.offlineProtocol.build(
+ Map.of("sn", sn)
+ );
+ this.clientSessionManager.broadcast(sn, message);
+ // TODO:释放连接
+ // TODO:释放房间
+ // TODO:退出房间
+ // TODO:退出帐号
+ // TODO:注意释放:是否考虑没有message(非正常的关闭)不要立即释放
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/RegisterListener.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/RegisterListener.java
index 0d906fe..be98001 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/RegisterListener.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/RegisterListener.java
@@ -7,14 +7,14 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.client.ClientSessionStatus;
import com.acgist.taoyao.signal.event.client.RegisterEvent;
import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter;
import com.acgist.taoyao.signal.protocol.client.OnlineProtocol;
-import com.acgist.taoyao.signal.session.ClientSession;
-import com.acgist.taoyao.signal.session.ClientSessionStatus;
/**
- * 终端注册监听
+ * 注册监听
*
* @author acgist
*/
@@ -31,16 +31,19 @@ public class RegisterListener extends ApplicationListenerAdapter
if (!session.authorized()) {
return;
}
- final Message message = this.onlineProtocol.build();
- message.setBody(Map.of("sn", session.sn()));
+ // 广播上线事件
+ final Message message = this.onlineProtocol.build(
+ Map.of("sn", session.sn())
+ );
this.clientSessionManager.broadcast(session.sn(), message);
- final Map, ?> data = event.getData();
+ // 修改终端状态
+ final Map, ?> body = event.getBody();
final ClientSessionStatus status = session.status();
status.setSn(session.sn());
- status.setIp((String) data.get("ip"));
- status.setMac((String) data.get("mac"));
- status.setSignal((Integer) data.get("signal"));
- status.setBattery((Integer) data.get("battery"));
+ status.setIp((String) body.get("ip"));
+ status.setMac((String) body.get("mac"));
+ status.setSignal((Integer) body.get("signal"));
+ status.setBattery((Integer) body.get("battery"));
}
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/ScriptListener.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/ScriptListener.java
new file mode 100644
index 0000000..6040a1b
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/ScriptListener.java
@@ -0,0 +1,66 @@
+package com.acgist.taoyao.signal.listener.platform;
+
+import java.io.InputStream;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.signal.event.platform.ScriptEvent;
+import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 执行命令监听
+ *
+ * @author acgist
+ */
+@Slf4j
+@Component
+public class ScriptListener extends ApplicationListenerAdapter {
+
+ @Async
+ @Override
+ public void onApplicationEvent(ScriptEvent event) {
+ final String script = (String) event.getBody().get("script");
+ log.debug("执行命令:{}", script);
+ this.execute(script);
+ }
+
+ /**
+ * 执行命令
+ *
+ * @param script 命令
+ */
+ private void execute(String script) {
+ if(StringUtils.isEmpty(script)) {
+ log.warn("执行命令失败:{}", script);
+ return;
+ }
+ Process process = null;
+ try {
+ process = Runtime.getRuntime().exec(script);
+ try(
+ final InputStream input = process.getInputStream();
+ final InputStream error = process.getErrorStream();
+ ) {
+ log.info("""
+ 执行命令:{}
+ 执行结果:{}
+ 失败结果:{}
+ """, script, new String(input.readAllBytes()), new String(error.readAllBytes()));
+ } catch (Exception e) {
+ log.error("命令执行异常:{}", script, e);
+ }
+ } catch (Exception e) {
+ log.error("执行命令异常:{}", script, e);
+ } finally {
+ if(process != null) {
+ process.destroy();
+// process.destroyForcibly();
+ }
+ }
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Protocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Protocol.java
index d4ec31a..6400418 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Protocol.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Protocol.java
@@ -1,18 +1,18 @@
package com.acgist.taoyao.signal.protocol;
-import org.springframework.context.ApplicationEvent;
-
import com.acgist.taoyao.boot.model.Message;
-import com.acgist.taoyao.signal.session.ClientSession;
+import com.acgist.taoyao.boot.model.MessageCode;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.event.ApplicationEventAdapter;
/**
- * 信令协议
+ * 信令
*
- * 1000~1999:系统信令(关机)
- * 2000~2999:终端信令(注册、注销、终端列表)
- * 3000~3999:直播信令
- * 4000~4999:会议信令
- * 9999:信令异常
+ * 1000~1999:平台信令
+ * 2000~2999:终端信令
+ * 3000~3999:会议信令
+ * 4000~4999:直播信令
+ * 5000~5999:媒体信令
*
* @author acgist
*/
@@ -21,7 +21,12 @@ public interface Protocol {
/**
* @return 信令协议标识
*/
- Integer protocol();
+ Integer pid();
+
+ /**
+ * @return 信令名称
+ */
+ String name();
/**
* 处理信令消息
@@ -29,10 +34,17 @@ public interface Protocol {
* @param sn 终端标识
* @param message 信令消息
* @param session 会话
- *
- * @return 事件
*/
- ApplicationEvent execute(String sn, Message message, ClientSession session);
+ void execute(String sn, Message message, ClientSession session);
+
+ /**
+ * 发布事件
+ *
+ * @param 事件类型
+ *
+ * @param event 事件
+ */
+ void publishEvent(E event);
/**
* 创建信令消息
@@ -41,4 +53,46 @@ public interface Protocol {
*/
Message build();
+ /**
+ * 创建信令消息
+ *
+ * @param body 请求响应主体
+ *
+ * @return 信令消息
+ */
+ Message build(Object body);
+
+ /**
+ * 创建信令消息
+ *
+ * @param code 响应编码
+ * @param body 请求响应主体
+ *
+ * @return 信令消息
+ */
+ Message build(MessageCode code, Object body);
+
+ /**
+ * 创建信令消息
+ *
+ * @param code 响应编码
+ * @param message 响应描述
+ * @param body 请求响应主体
+ *
+ * @return 信令消息
+ */
+ Message build(MessageCode code, String message, Object body);
+
+ /**
+ * 创建信令消息
+ *
+ * @param id 请求响应标识
+ * @param code 响应编码
+ * @param message 响应描述
+ * @param body 请求响应主体
+ *
+ * @return 信令消息
+ */
+ Message build(String id, MessageCode code, String message, Object body);
+
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolAdapter.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolAdapter.java
index 3b569bf..f4524cd 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolAdapter.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolAdapter.java
@@ -1,49 +1,102 @@
package com.acgist.taoyao.signal.protocol;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
import com.acgist.taoyao.boot.config.TaoyaoProperties;
import com.acgist.taoyao.boot.model.Header;
import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.boot.model.MessageCode;
import com.acgist.taoyao.boot.service.IdService;
+import com.acgist.taoyao.signal.event.ApplicationEventAdapter;
/**
- * 信令协议适配器
+ * 信令适配器
*
* @author acgist
*/
public abstract class ProtocolAdapter implements Protocol {
@Autowired
- private IdService idService;
+ protected IdService idService;
+ @Autowired
+ protected ApplicationContext context;
@Autowired
protected TaoyaoProperties taoyaoProperties;
/**
- * 信令协议标识
+ * 信令标识
*/
- protected final Integer protocol;
+ protected final Integer pid;
+ /**
+ * 信令名称
+ */
+ protected final String name;
- protected ProtocolAdapter(Integer protocol) {
- this.protocol = protocol;
+ protected ProtocolAdapter(Integer pid, String name) {
+ this.pid = pid;
+ this.name = name;
}
@Override
- public Integer protocol() {
- return this.protocol;
+ public Integer pid() {
+ return this.pid;
+ }
+
+ @Override
+ public String name() {
+ return this.name;
+ }
+
+ @Override
+ public void publishEvent(E event) {
+ this.context.publishEvent(event);
}
@Override
public Message build() {
+ return this.build(null, null, null, null);
+ }
+
+ @Override
+ public Message build(Object body) {
+ return this.build(null, null, null, body);
+ }
+
+ @Override
+ public Message build(MessageCode code, Object body) {
+ return this.build(null, code, null, body);
+ }
+
+ @Override
+ public Message build(MessageCode code, String message, Object body) {
+ return this.build(null, code, message, body);
+ }
+
+ @Override
+ public Message build(String id, MessageCode code, String message, Object body) {
+ if(StringUtils.isEmpty(id)) {
+ id = this.taoyaoProperties.getVersion();
+ }
final Header header = Header.builder()
.v(this.taoyaoProperties.getVersion())
- .id(this.idService.buildIdToString())
- .pid(this.protocol)
+ .id(id)
+ .pid(this.pid)
.build();
- final Message message = Message.builder()
+ final Message build = Message.builder()
.header(header)
.build();
- return message;
+ if(code != null) {
+ build.setCode(code);
+ }
+ if(StringUtils.isNotEmpty(message)) {
+ build.setMessage(message);
+ }
+ if(body != null) {
+ build.setBody(body);
+ }
+ return build;
}
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolBodyMapAdapter.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolBodyMapAdapter.java
deleted file mode 100644
index 22fb3e6..0000000
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolBodyMapAdapter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.acgist.taoyao.signal.protocol;
-
-import java.util.Map;
-
-import org.springframework.context.ApplicationEvent;
-
-import com.acgist.taoyao.boot.model.Message;
-import com.acgist.taoyao.boot.model.MessageCodeException;
-import com.acgist.taoyao.signal.session.ClientSession;
-
-/**
- * 信令协议Map主体适配器
- *
- * @author acgist
- */
-public abstract class ProtocolBodyMapAdapter extends ProtocolAdapter {
-
- protected ProtocolBodyMapAdapter(Integer protocol) {
- super(protocol);
- }
-
- @Override
- public ApplicationEvent execute(String sn, Message message, ClientSession session) {
- final Object body = message.getBody();
- if(body instanceof Map, ?> map) {
- return this.execute(sn, map, message, session);
- } else {
- throw MessageCodeException.of("信令主体类型错误:" + message);
- }
- }
-
- /**
- * 处理信令消息
- *
- * @param sn 终端标识
- * @param body 消息主体
- * @param message 信令消息
- * @param session 会话
- *
- * @return 事件
- */
- public abstract ApplicationEvent execute(String sn, Map, ?> body, Message message, ClientSession session);
-
-}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolBodyObjectAdapter.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolJavaAdapter.java
similarity index 59%
rename from taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolBodyObjectAdapter.java
rename to taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolJavaAdapter.java
index c5388e5..a6c394f 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolBodyObjectAdapter.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolJavaAdapter.java
@@ -3,38 +3,37 @@ package com.acgist.taoyao.signal.protocol;
import java.util.Map;
import org.springframework.cglib.beans.BeanMap;
-import org.springframework.context.ApplicationEvent;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.boot.model.MessageCodeException;
import com.acgist.taoyao.boot.utils.BeanUtils;
-import com.acgist.taoyao.signal.session.ClientSession;
+import com.acgist.taoyao.signal.client.ClientSession;
/**
- * 信令协议对象主体适配器
+ * Java主体信令适配器
*
* @author acgist
*/
-public abstract class ProtocolBodyObjectAdapter extends ProtocolAdapter {
+public abstract class ProtocolJavaAdapter extends ProtocolAdapter {
/**
* 对象类型
*/
private final Class clazz;
- protected ProtocolBodyObjectAdapter(Integer protocol, Class clazz) {
- super(protocol);
+ protected ProtocolJavaAdapter(Integer pid, String name, Class clazz) {
+ super(pid, name);
this.clazz = clazz;
}
@Override
- public ApplicationEvent execute(String sn, Message message, ClientSession session) {
+ public void execute(String sn, Message message, ClientSession session) {
final Object body = message.getBody();
if(body instanceof Map, ?> map) {
final T t = BeanUtils.newInstance(this.clazz);
final BeanMap beanMap = BeanMap.create(t);
beanMap.putAll(map);
- return this.execute(sn, t, message, session);
+ this.execute(sn, t, message, session);
} else {
throw MessageCodeException.of("信令主体类型错误:" + message);
}
@@ -47,9 +46,7 @@ public abstract class ProtocolBodyObjectAdapter extends ProtocolAdapter {
* @param body 消息主体
* @param message 信令消息
* @param session 会话
- *
- * @return 事件
*/
- public abstract ApplicationEvent execute(String sn, T body, Message message, ClientSession session);
+ public abstract void execute(String sn, T body, Message message, ClientSession session);
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolManager.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolManager.java
index 4d03193..6f88e0e 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolManager.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolManager.java
@@ -5,19 +5,19 @@ import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
-import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Service;
import com.acgist.taoyao.boot.model.Header;
import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.boot.model.MessageCode;
import com.acgist.taoyao.boot.model.MessageCodeException;
import com.acgist.taoyao.boot.utils.JSONUtils;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.client.ClientSessionManager;
import com.acgist.taoyao.signal.protocol.client.RegisterProtocol;
-import com.acgist.taoyao.signal.session.ClientSession;
-import com.acgist.taoyao.signal.session.ClientSessionManager;
+import com.acgist.taoyao.signal.protocol.platform.ErrorProtocol;
import lombok.extern.slf4j.Slf4j;
@@ -38,18 +38,25 @@ public class ProtocolManager {
@Autowired
private ApplicationContext context;
@Autowired
+ private ErrorProtocol errorProtocol;
+ @Autowired
private ClientSessionManager clientSessionManager;
@PostConstruct
public void init() {
final Map map = this.context.getBeansOfType(Protocol.class);
- map.forEach((k, v) -> {
- final Integer protocol = v.protocol();
- if(this.protocolMapping.containsKey(protocol)) {
- throw MessageCodeException.of("存在重复信令协议:" + protocol);
+ map.entrySet().stream()
+ .sorted((a, z) -> Integer.compare(a.getValue().pid(), z.getValue().pid()))
+ .forEach(e -> {
+ final String k = e.getKey();
+ final Protocol v = e.getValue();
+ final Integer pid = v.pid();
+ final String name = v.name();
+ if(this.protocolMapping.containsKey(pid)) {
+ throw MessageCodeException.of("存在重复信令协议:" + pid);
}
- log.info("注册信令协议:{}-{}", protocol, k);
- this.protocolMapping.put(protocol, v);
+ log.info("注册信令协议:{}-{}-{}", pid, name, k);
+ this.protocolMapping.put(pid, v);
});
}
@@ -61,38 +68,39 @@ public class ProtocolManager {
*/
public void execute(String message, AutoCloseable instance) {
log.debug("执行信令消息:{}", message);
- if(StringUtils.isEmpty(message)) {
- log.warn("消息为空:{}", message);
+ // 验证请求
+ final Message value = JSONUtils.toJava(message, Message.class);
+ if(value == null) {
+ log.warn("消息格式错误(解析失败):{}", message);
return;
}
- final Message value = JSONUtils.toJava(message, Message.class);
final Header header = value.getHeader();
if(header == null) {
log.warn("消息格式错误(没有头部):{}", message);
return;
}
+ final String id = header.getId();
final String sn = header.getSn();
final Integer pid = header.getPid();
- if(sn == null || pid == null) {
- log.warn("消息格式错误(没有SN或者PID):{}", message);
+ if(id == null || sn == null || pid == null) {
+ log.warn("消息格式错误(id|sn|pid):{}", message);
return;
}
+ // 设置缓存ID
+ this.errorProtocol.set(id);
+ // 开始处理协议
final Protocol protocol = this.protocolMapping.get(pid);
if(protocol == null) {
log.warn("不支持的信令协议:{}", message);
return;
}
- ApplicationEvent event = null;
final ClientSession session = this.clientSessionManager.session(instance);
- if(session != null && protocol instanceof RegisterProtocol) {
- event = protocol.execute(sn, value, session);
- } else if(session != null && session.authorized()) {
- event = protocol.execute(sn, value, session);
+ if(protocol instanceof RegisterProtocol) {
+ protocol.execute(sn, value, session);
+ } else if(session.authorized() && sn.equals(session.sn())) {
+ protocol.execute(sn, value, session);
} else {
- log.warn("会话没有权限:{}", message);
- }
- if(event != null) {
- this.context.publishEvent(event);
+ session.push(this.errorProtocol.build(MessageCode.CODE_3401, "终端会话没有授权"));
}
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMapAdapter.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMapAdapter.java
new file mode 100644
index 0000000..27fb94e
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMapAdapter.java
@@ -0,0 +1,40 @@
+package com.acgist.taoyao.signal.protocol;
+
+import java.util.Map;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.boot.model.MessageCodeException;
+import com.acgist.taoyao.signal.client.ClientSession;
+
+/**
+ * Map主体信令适配器
+ *
+ * @author acgist
+ */
+public abstract class ProtocolMapAdapter extends ProtocolAdapter {
+
+ protected ProtocolMapAdapter(Integer pid, String name) {
+ super(pid, name);
+ }
+
+ @Override
+ public void execute(String sn, Message message, ClientSession session) {
+ final Object body = message.getBody();
+ if(body instanceof Map, ?> map) {
+ this.execute(sn, map, message, session);
+ } else {
+ throw MessageCodeException.of("信令主体类型错误:" + message);
+ }
+ }
+
+ /**
+ * 处理信令消息
+ *
+ * @param sn 终端标识
+ * @param body 消息主体
+ * @param message 信令消息
+ * @param session 会话
+ */
+ public abstract void execute(String sn, Map, ?> body, Message message, ClientSession session);
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/BroadcastProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/BroadcastProtocol.java
new file mode 100644
index 0000000..8444468
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/BroadcastProtocol.java
@@ -0,0 +1,36 @@
+package com.acgist.taoyao.signal.protocol.client;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.client.ClientSessionManager;
+import com.acgist.taoyao.signal.protocol.ProtocolAdapter;
+
+/**
+ * 广播信令
+ *
+ * @author acgist
+ */
+@Component
+public class BroadcastProtocol extends ProtocolAdapter {
+
+ /**
+ * 信令协议标识
+ */
+ public static final Integer PID = 2009;
+
+ @Autowired
+ private ClientSessionManager clientSessionManager;
+
+ public BroadcastProtocol() {
+ super(PID, "广播信令");
+ }
+
+ @Override
+ public void execute(String sn, Message message, ClientSession session) {
+ this.clientSessionManager.broadcast(sn, message);
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/CloseProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/CloseProtocol.java
index 7899054..545dc28 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/CloseProtocol.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/CloseProtocol.java
@@ -1,17 +1,19 @@
package com.acgist.taoyao.signal.protocol.client;
-import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;
import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
import com.acgist.taoyao.signal.protocol.ProtocolAdapter;
-import com.acgist.taoyao.signal.session.ClientSession;
+
+import lombok.extern.slf4j.Slf4j;
/**
- * 关闭信令协议
+ * 关闭信令
*
* @author acgist
*/
+@Slf4j
@Component
public class CloseProtocol extends ProtocolAdapter {
@@ -21,13 +23,18 @@ public class CloseProtocol extends ProtocolAdapter {
public static final Integer PID = 2001;
public CloseProtocol() {
- super(PID);
+ super(PID, "关闭信令");
}
@Override
- public ApplicationEvent execute(String sn, Message message, ClientSession session) {
- // TODO
- return null;
+ public void execute(String sn, Message message, ClientSession session) {
+ // 关闭不会响应
+ try {
+ session.close();
+ } catch (Exception e) {
+ log.error("关闭终端异常", e);
+ }
+ // 不用发布事件:关闭连接后会发布事件
}
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/HeartbeatProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/HeartbeatProtocol.java
new file mode 100644
index 0000000..19053c2
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/HeartbeatProtocol.java
@@ -0,0 +1,39 @@
+package com.acgist.taoyao.signal.protocol.client;
+
+import java.util.Map;
+
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.client.ClientSessionStatus;
+import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter;
+
+/**
+ * 心跳信令
+ *
+ * @author acgist
+ */
+@Component
+public class HeartbeatProtocol extends ProtocolMapAdapter {
+
+ /**
+ * 信令协议标识
+ */
+ public static final Integer PID = 2005;
+
+ public HeartbeatProtocol() {
+ super(PID, "心跳信令");
+ }
+
+ @Override
+ public void execute(String sn, Map, ?> body, Message message, ClientSession session) {
+ // 回应心跳
+ session.push(message.cloneWidthoutBody());
+ // 设置状态
+ final ClientSessionStatus status = session.status();
+ status.setSignal((Integer) body.get("signal"));
+ status.setBattery((Integer) body.get("battery"));
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ListProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ListProtocol.java
new file mode 100644
index 0000000..0233750
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ListProtocol.java
@@ -0,0 +1,37 @@
+package com.acgist.taoyao.signal.protocol.client;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.client.ClientSessionManager;
+import com.acgist.taoyao.signal.protocol.ProtocolAdapter;
+
+/**
+ * 终端列表信令
+ *
+ * @author acgist
+ */
+@Component
+public class ListProtocol extends ProtocolAdapter {
+
+ /**
+ * 信令协议标识
+ */
+ public static final Integer PID = 2006;
+
+ @Autowired
+ private ClientSessionManager clientSessionManager;
+
+ public ListProtocol() {
+ super(PID, "终端列表信令");
+ }
+
+ @Override
+ public void execute(String sn, Message message, ClientSession session) {
+ message.setBody(this.clientSessionManager.status());
+ session.push(message);
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/OfflineProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/OfflineProtocol.java
index 16ab85c..adba5d4 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/OfflineProtocol.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/OfflineProtocol.java
@@ -1,10 +1,31 @@
package com.acgist.taoyao.signal.protocol.client;
-public class OfflineProtocol {
+import org.springframework.stereotype.Component;
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.protocol.ProtocolAdapter;
+
+/**
+ * 终端下线信令
+ *
+ * @author acgist
+ */
+@Component
+public class OfflineProtocol extends ProtocolAdapter {
+
/**
* 信令协议标识
*/
public static final Integer PID = 2003;
+
+ public OfflineProtocol() {
+ super(PID, "终端下线信令");
+ }
+
+ @Override
+ public void execute(String sn, Message message, ClientSession session) {
+ // 忽略
+ }
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/OnlineProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/OnlineProtocol.java
index 0e911d0..8214788 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/OnlineProtocol.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/OnlineProtocol.java
@@ -1,14 +1,13 @@
package com.acgist.taoyao.signal.protocol.client;
-import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;
import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
import com.acgist.taoyao.signal.protocol.ProtocolAdapter;
-import com.acgist.taoyao.signal.session.ClientSession;
/**
- * 上线信令协议
+ * 上线信令
*
* @author acgist
*/
@@ -21,12 +20,12 @@ public class OnlineProtocol extends ProtocolAdapter {
public static final Integer PID = 2002;
public OnlineProtocol() {
- super(PID);
+ super(PID, "上线信令");
}
@Override
- public ApplicationEvent execute(String sn, Message message, ClientSession session) {
- return null;
+ public void execute(String sn, Message message, ClientSession session) {
+ // 忽略
}
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/RegisterProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/RegisterProtocol.java
index 3be60fb..60f8dca 100644
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/RegisterProtocol.java
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/RegisterProtocol.java
@@ -4,23 +4,22 @@ import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;
import com.acgist.taoyao.boot.config.SecurityProperties;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.boot.model.MessageCode;
+import com.acgist.taoyao.signal.client.ClientSession;
import com.acgist.taoyao.signal.event.client.RegisterEvent;
-import com.acgist.taoyao.signal.protocol.ProtocolBodyMapAdapter;
-import com.acgist.taoyao.signal.session.ClientSession;
+import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter;
/**
- * 注册信令协议
+ * 注册信令
*
* @author acgist
*/
@Component
-public class RegisterProtocol extends ProtocolBodyMapAdapter {
+public class RegisterProtocol extends ProtocolMapAdapter {
/**
* 信令协议标识
@@ -31,14 +30,16 @@ public class RegisterProtocol extends ProtocolBodyMapAdapter {
private SecurityProperties securityProperties;
public RegisterProtocol() {
- super(PID);
+ super(PID, "注册信令");
}
@Override
- public ApplicationEvent execute(String sn, Map, ?> body, Message message, ClientSession session) {
+ public void execute(String sn, Map, ?> body, Message message, ClientSession session) {
final String username = (String) body.get("username");
final String password = (String) body.get("password");
+ // 如果需要终端鉴权在此实现
if(
+ Boolean.FALSE.equals(this.securityProperties.getEnabled()) ||
StringUtils.equals(this.securityProperties.getUsername(), username) &&
StringUtils.equals(this.securityProperties.getPassword(), password)
) {
@@ -47,8 +48,10 @@ public class RegisterProtocol extends ProtocolBodyMapAdapter {
} else {
message.setCode(MessageCode.CODE_3401);
}
- session.push(message);
- return new RegisterEvent(session, body);
+ // 推送消息
+ session.push(message.cloneWidthoutBody());
+ // 发送事件
+ this.publishEvent(new RegisterEvent(body, message, session));
}
}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/StatusProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/StatusProtocol.java
new file mode 100644
index 0000000..43e8692
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/StatusProtocol.java
@@ -0,0 +1,53 @@
+package com.acgist.taoyao.signal.protocol.client;
+
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.client.ClientSessionManager;
+import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 终端状态信令
+ *
+ * @author acgist
+ */
+@Slf4j
+@Component
+public class StatusProtocol extends ProtocolMapAdapter {
+
+ /**
+ * 信令协议标识
+ */
+ public static final Integer PID = 2007;
+
+ @Autowired
+ private ClientSessionManager clientSessionManager;
+
+ public StatusProtocol() {
+ super(PID, "终端状态信令");
+ }
+
+ @Override
+ public void execute(String sn, Map, ?> body, Message message, ClientSession session) {
+ String querySn = (String) body.get("sn");
+ // 如果没有指定终端标识默认查询自己
+ if(StringUtils.isEmpty(querySn)) {
+ querySn = sn;
+ }
+ final ClientSession clientSession = this.clientSessionManager.session(querySn);
+ if(clientSession != null) {
+ message.setBody(clientSession.status());
+ session.push(message);
+ } else {
+ log.warn("终端无效:{}", querySn);
+ }
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/UnicastProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/UnicastProtocol.java
new file mode 100644
index 0000000..64267f0
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/UnicastProtocol.java
@@ -0,0 +1,47 @@
+package com.acgist.taoyao.signal.protocol.client;
+
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.client.ClientSessionManager;
+import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 单播信令
+ *
+ * @author acgist
+ */
+@Slf4j
+@Component
+public class UnicastProtocol extends ProtocolMapAdapter {
+
+ /**
+ * 信令协议标识
+ */
+ public static final Integer PID = 2008;
+
+ @Autowired
+ private ClientSessionManager clientSessionManager;
+
+ public UnicastProtocol() {
+ super(PID, "单播信令");
+ }
+
+ @Override
+ public void execute(String sn, Map, ?> body, Message message, ClientSession session) {
+ final String to = (String) body.remove("to");
+ if(StringUtils.isNotEmpty(to)) {
+ this.clientSessionManager.unicast(to, message);
+ } else {
+ log.warn("单播消息没有接收终端标识:{}", to);
+ }
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ErrorProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ErrorProtocol.java
new file mode 100644
index 0000000..6b8776c
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ErrorProtocol.java
@@ -0,0 +1,56 @@
+package com.acgist.taoyao.signal.protocol.platform;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.boot.model.MessageCode;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.protocol.ProtocolAdapter;
+
+/**
+ * 异常信令
+ *
+ * @author acgist
+ */
+@Component
+public class ErrorProtocol extends ProtocolAdapter {
+
+ /**
+ * 信令协议标识
+ */
+ public static final Integer PID = 1999;
+
+ /**
+ * 请求ID缓存
+ */
+ private InheritableThreadLocal idLocal = new InheritableThreadLocal<>();
+
+ public ErrorProtocol() {
+ super(PID, "异常信令");
+ }
+
+ /**
+ * @param id 请求ID
+ */
+ public void set(String id) {
+ this.idLocal.set(id);
+ }
+
+ @Override
+ public void execute(String sn, Message message, ClientSession session) {
+ }
+
+ @Override
+ public Message build(String id, MessageCode code, String message, Object body) {
+ final String oldId = this.idLocal.get();
+ if(StringUtils.isEmpty(oldId)) {
+ id = this.idService.buildIdToString();
+ } else {
+ id = oldId;
+ this.idLocal.remove();
+ }
+ return super.build(id, code, message, body);
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ScriptProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ScriptProtocol.java
new file mode 100644
index 0000000..1c11342
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ScriptProtocol.java
@@ -0,0 +1,34 @@
+package com.acgist.taoyao.signal.protocol.platform;
+
+import java.util.Map;
+
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.event.platform.ScriptEvent;
+import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter;
+
+/**
+ * 执行命令信令
+ *
+ * @author acgist
+ */
+@Component
+public class ScriptProtocol extends ProtocolMapAdapter {
+
+ /**
+ * 信令协议标识
+ */
+ public static final Integer PID = 1001;
+
+ public ScriptProtocol() {
+ super(PID, "执行命令信令");
+ }
+
+ @Override
+ public void execute(String sn, Map, ?> body, Message message, ClientSession session) {
+ this.publishEvent(new ScriptEvent(body, message, session));
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ShutdownProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ShutdownProtocol.java
new file mode 100644
index 0000000..3bc4f15
--- /dev/null
+++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/ShutdownProtocol.java
@@ -0,0 +1,42 @@
+package com.acgist.taoyao.signal.protocol.platform;
+
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.stereotype.Component;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.ClientSession;
+import com.acgist.taoyao.signal.protocol.ProtocolAdapter;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 关闭服务信令
+ *
+ * @author acgist
+ */
+@Slf4j
+@Component
+public class ShutdownProtocol extends ProtocolAdapter {
+
+ /**
+ * 信令协议标识
+ */
+ public static final Integer PID = 1000;
+
+ public ShutdownProtocol() {
+ super(PID, "关闭服务信令");
+ }
+
+ @Override
+ public void execute(String sn, Message message, ClientSession session) {
+ if(this.context instanceof ConfigurableApplicationContext context) {
+ log.info("关闭服务:{}", sn);
+ if(context.isActive()) {
+ context.close();
+ }
+ } else {
+ log.info("关闭服务失败:{}", sn);
+ }
+ }
+
+}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/ErrorProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/ErrorProtocol.java
deleted file mode 100644
index 6449219..0000000
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/ErrorProtocol.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.acgist.taoyao.signal.protocol.system;
-
-import org.springframework.context.ApplicationEvent;
-import org.springframework.stereotype.Component;
-
-import com.acgist.taoyao.boot.model.Message;
-import com.acgist.taoyao.signal.protocol.ProtocolAdapter;
-import com.acgist.taoyao.signal.session.ClientSession;
-
-/**
- * 异常信令协议
- *
- * @author acgist
- */
-@Component
-public class ErrorProtocol extends ProtocolAdapter {
-
- /**
- * 信令协议标识
- */
- public static final Integer PID = 9999;
-
- public ErrorProtocol() {
- super(PID);
- }
-
- @Override
- public ApplicationEvent execute(String sn, Message message, ClientSession session) {
- return null;
- }
-
-}
diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/HeartbeatProtocol.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/HeartbeatProtocol.java
deleted file mode 100644
index 0e52318..0000000
--- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/HeartbeatProtocol.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.acgist.taoyao.signal.protocol.system;
-
-import org.springframework.context.ApplicationEvent;
-import org.springframework.stereotype.Component;
-
-import com.acgist.taoyao.boot.model.Message;
-import com.acgist.taoyao.signal.protocol.ProtocolAdapter;
-import com.acgist.taoyao.signal.session.ClientSession;
-
-/**
- * 心跳信令协议
- *
- * @author acgist
- */
-@Component
-public class HeartbeatProtocol extends ProtocolAdapter {
-
- /**
- * 信令协议标识
- */
- public static final Integer PID = 1000;
-
- public HeartbeatProtocol() {
- super(PID);
- }
-
- @Override
- public ApplicationEvent execute(String sn, Message message, ClientSession session) {
- session.push(message);
- return null;
- }
-
-}
diff --git a/taoyao-test/src/main/java/com/acgist/taoyao/test/annotation/CostedTestTestExecutionListener.java b/taoyao-test/src/main/java/com/acgist/taoyao/test/annotation/CostedTestTestExecutionListener.java
index 96d3667..fa9eb10 100644
--- a/taoyao-test/src/main/java/com/acgist/taoyao/test/annotation/CostedTestTestExecutionListener.java
+++ b/taoyao-test/src/main/java/com/acgist/taoyao/test/annotation/CostedTestTestExecutionListener.java
@@ -22,6 +22,9 @@ public class CostedTestTestExecutionListener implements TestExecutionListener {
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
final CostedTest costedTest = testContext.getTestMethod().getDeclaredAnnotation(CostedTest.class);
+ if(costedTest == null) {
+ return;
+ }
final int count = costedTest.count();
final int thread = costedTest.thread();
final long timeout = costedTest.timeout();
diff --git a/taoyao-webrtc/README.md b/taoyao-webrtc/README.md
index 766668a..1a25a90 100644
--- a/taoyao-webrtc/README.md
+++ b/taoyao-webrtc/README.md
@@ -50,8 +50,3 @@ SDP只是一种信息格式的描述标准,不属于传输协议,但是可
|会话通道|SIP/SDP|
|媒体通道|RTP/RTCP/SRTP/SRTCP|
-## WebRTC资料
-
-[GB28181](https://blog.csdn.net/jisuanji111111/article/details/121634199)
-[WebRTC协议](http://www.manoner.com/post/音视频基础/WebRTC核心组件和协议栈/)
-[WebRTC开源项目](https://blog.csdn.net/ababab12345/article/details/115585378)
diff --git a/taoyao-webrtc/pom.xml b/taoyao-webrtc/pom.xml
index 79dbf4c..830ce97 100644
--- a/taoyao-webrtc/pom.xml
+++ b/taoyao-webrtc/pom.xml
@@ -27,7 +27,7 @@
com.acgist
- taoyao-boot
+ taoyao-signal