diff --git a/README.md b/README.md
index 4839c4a..8a05654 100644
--- a/README.md
+++ b/README.md
@@ -33,17 +33,16 @@
|功能|是否支持|是否实现|描述|
|:--|:--|:--|:--|
|P2P|支持|完成|P2P监控模式|
-|WebRTC|支持|完成|Web终端不能同时进入多个房间|
-|控制|支持|完成|实现所有控制信令|
+|WebRTC|支持|完成|视频房间|
+|控制|支持|完成|完整控制信令|
### 安卓终端功能
|功能|是否支持|是否实现|描述|
|:--|:--|:--|:--|
-|P2P|支持|实现|P2P监控模式|
-|WebRTC|支持|暂未实现|安卓终端支持同时进入多个房间|
-|RTP|支持|暂未实现|支持房间RTP推流(不会拉流)|
-|控制|支持|完成|实现部分控制信令|
+|P2P|支持|完成|P2P监控模式|
+|WebRTC|支持|完成|视频房间|
+|控制|支持|完成|部分控制信令|
|拍照|支持|完成|拍照|
|录像|支持|完成|录制|
|变声|支持|暂未实现|变声器|
@@ -51,6 +50,8 @@
|美颜|支持|暂未实现|视频美颜|
|AI识别|支持|暂未实现|视频AI识别|
+> 注意:Web不支持同时进入多个视频房间,安卓终端支持同时进入多个视频房间。
+
## 证书
本地开发测试安装`docs/certs`中的`ca.crt`证书到`受信任的根证书颁发机构`
diff --git a/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MainActivity.java b/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MainActivity.java
index ecac7cf..eec658a 100644
--- a/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MainActivity.java
+++ b/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MainActivity.java
@@ -27,7 +27,6 @@ import androidx.core.app.ActivityCompat;
import com.acgist.taoyao.client.databinding.ActivityMainBinding;
import com.acgist.taoyao.client.signal.Taoyao;
import com.acgist.taoyao.media.MediaManager;
-import com.acgist.taoyao.media.TransportType;
import com.acgist.taoyao.media.VideoSourceType;
import com.acgist.taoyao.media.config.Config;
@@ -128,7 +127,6 @@ public class MainActivity extends AppCompatActivity implements Serializable {
resources.getInteger(R.integer.iFrameInterval),
resources.getString(R.string.storagePathImage),
resources.getString(R.string.storagePathVideo),
- TransportType.valueOf(resources.getString(R.string.transportType)),
VideoSourceType.valueOf(resources.getString(R.string.videoSourceType))
);
final Display display = this.getWindow().getContext().getDisplay();
diff --git a/taoyao-client-android/taoyao/client/src/main/res/values/settings.xml b/taoyao-client-android/taoyao/client/src/main/res/values/settings.xml
index c80c13a..ed60c05 100644
--- a/taoyao-client-android/taoyao/client/src/main/res/values/settings.xml
+++ b/taoyao-client-android/taoyao/client/src/main/res/values/settings.xml
@@ -16,11 +16,10 @@
DES
2SPWy+TF1zM=
-
+
/taoyao/image
+
/taoyao/video
-
- WEBRTC
BACK
@@ -35,9 +34,14 @@
true
true
+
100
+
fd-audio
+
fd-video
+
1
+
1
\ No newline at end of file
diff --git a/taoyao-client-android/taoyao/media/CMakeLists.txt b/taoyao-client-android/taoyao/media/CMakeLists.txt
index 77b8dea..8276397 100644
--- a/taoyao-client-android/taoyao/media/CMakeLists.txt
+++ b/taoyao-client-android/taoyao/media/CMakeLists.txt
@@ -29,12 +29,6 @@ set(
${SOURCE_DIR}/include/MediaManager.hpp
${SOURCE_DIR}/include/Room.hpp
${SOURCE_DIR}/include/RouterCallback.hpp
- ${SOURCE_DIR}/include/RtpAudioPublisher.hpp
- ${SOURCE_DIR}/include/RtpClient.hpp
- ${SOURCE_DIR}/include/RtpVideoPublisher.hpp
- ${SOURCE_DIR}/rtp/RtpAudioPublisher.cpp
- ${SOURCE_DIR}/rtp/RtpClient.cpp
- ${SOURCE_DIR}/rtp/RtpVideoPublisher.cpp
${SOURCE_DIR}/webrtc/MediaManager.cpp
${SOURCE_DIR}/webrtc/Room.cpp
${SOURCE_DIR}/webrtc/RouterCallback.cpp
diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpAudioPublisher.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpAudioPublisher.hpp
deleted file mode 100644
index f7883f8..0000000
--- a/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpAudioPublisher.hpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-namespace acgist {
-
-}
\ No newline at end of file
diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpClient.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpClient.hpp
deleted file mode 100644
index f7883f8..0000000
--- a/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpClient.hpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-namespace acgist {
-
-}
\ No newline at end of file
diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpVideoPublisher.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpVideoPublisher.hpp
deleted file mode 100644
index f7883f8..0000000
--- a/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpVideoPublisher.hpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-namespace acgist {
-
-}
\ No newline at end of file
diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpAudioPublisher.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpAudioPublisher.cpp
deleted file mode 100644
index 92abd1e..0000000
--- a/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpAudioPublisher.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "RtpAudioPublisher.hpp"
-
-namespace acgist {
-
-}
\ No newline at end of file
diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpClient.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpClient.cpp
deleted file mode 100644
index 9870cfa..0000000
--- a/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpClient.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "RtpClient.hpp"
-
-namespace acgist {
-
-}
\ No newline at end of file
diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpVideoPublisher.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpVideoPublisher.cpp
deleted file mode 100644
index 6717f7a..0000000
--- a/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpVideoPublisher.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "RtpVideoPublisher.hpp"
-
-namespace acgist {
-
-}
\ No newline at end of file
diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/Room.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/Room.cpp
index 0c12d33..b5086c6 100644
--- a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/Room.cpp
+++ b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/Room.cpp
@@ -32,7 +32,6 @@ namespace acgist {
}
void OnConnectionStateChange(mediasoupclient::Transport* transport, const std::string& connectionState) override {
- // TODO:restartIce?
}
std::future OnProduce(mediasoupclient::SendTransport* transport, const std::string& kind, nlohmann::json rtpParameters, const nlohmann::json& appData) override {
@@ -401,7 +400,6 @@ namespace acgist {
// webrtc::PeerConnectionInterface::RTCConfiguration rtcConfiguration(webrtc::PeerConnectionInterface::RTCConfigurationType::kSafe);
webrtc::PeerConnectionInterface::RTCConfiguration rtcConfiguration(webrtc::PeerConnectionInterface::RTCConfigurationType::kAggressive);
webrtc::JavaParamRef jRtcConfigurationRef(env, jRtcConfiguration);
- // 注意
webrtc::jni::JavaToNativeRTCConfiguration(env, jRtcConfigurationRef, &rtcConfiguration);
const char* rtpCapabilities = env->GetStringUTFChars(jRtpCapabilities, nullptr);
room->enterRoom(
diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaManager.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaManager.java
index 2a84a5b..3afa3f7 100644
--- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaManager.java
+++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaManager.java
@@ -2,8 +2,6 @@ package com.acgist.taoyao.media;
import android.content.Context;
import android.content.Intent;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
import android.media.projection.MediaProjection;
import android.os.Handler;
import android.os.Message;
@@ -43,8 +41,6 @@ import org.webrtc.VideoTrack;
import org.webrtc.audio.JavaAudioDeviceModule;
import java.util.Arrays;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
/**
* 媒体来源管理器
@@ -93,10 +89,6 @@ public final class MediaManager {
* 关键帧频率
*/
private int iFrameInterval;
- /**
- * 传输通道类型
- */
- private TransportType transportType;
/**
* 视频来源类型
*/
@@ -214,7 +206,7 @@ public final class MediaManager {
int imageQuantity, String audioQuantity, String videoQuantity,
int channelCount, int iFrameInterval,
String imagePath, String videoPath,
- TransportType transportType, VideoSourceType videoSourceType
+ VideoSourceType videoSourceType
) {
this.mainHandler = mainHandler;
this.context = context;
@@ -225,7 +217,6 @@ public final class MediaManager {
this.iFrameInterval = iFrameInterval;
this.imagePath = imagePath;
this.videoPath = videoPath;
- this.transportType = transportType;
this.videoSourceType = videoSourceType;
}
diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/TransportType.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/TransportType.java
deleted file mode 100644
index e298321..0000000
--- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/TransportType.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.acgist.taoyao.media;
-
-/**
- * 传输类型
- *
- * @author acgist
- */
-public enum TransportType {
-
- /**
- * RTP
- * 注意:只能监控
- */
- RTP,
- /**
- * WebRTC
- */
- WEBRTC;
-
-}
\ No newline at end of file
diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/audio/AudioMixer.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/audio/AudioMixer.java
index 15aa8a8..2b6af8f 100644
--- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/audio/AudioMixer.java
+++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/audio/AudioMixer.java
@@ -1,8 +1,5 @@
package com.acgist.taoyao.media.audio;
-import org.webrtc.voiceengine.WebRtcAudioManager;
-import org.webrtc.voiceengine.WebRtcAudioRecord;
-
/**
* 混音
*
diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RecordClient.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RecordClient.java
index c4fd242..85e33b3 100644
--- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RecordClient.java
+++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RecordClient.java
@@ -11,7 +11,6 @@ import android.util.Log;
import com.acgist.taoyao.boot.utils.DateUtils;
import com.acgist.taoyao.media.MediaManager;
-import com.acgist.taoyao.media.VideoSourceType;
import com.acgist.taoyao.media.signal.ITaoyao;
import org.webrtc.VideoFrame;
diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/Room.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/Room.java
index 962d6c3..acf15eb 100644
--- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/Room.java
+++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/Room.java
@@ -8,11 +8,8 @@ import com.acgist.taoyao.boot.utils.JSONUtils;
import com.acgist.taoyao.boot.utils.MapUtils;
import com.acgist.taoyao.boot.utils.PointerUtils;
import com.acgist.taoyao.media.RouterCallback;
-import com.acgist.taoyao.media.VideoSourceType;
import com.acgist.taoyao.media.config.Config;
-import com.acgist.taoyao.media.config.MediaAudioProperties;
import com.acgist.taoyao.media.config.MediaProperties;
-import com.acgist.taoyao.media.config.MediaVideoProperties;
import com.acgist.taoyao.media.config.WebrtcProperties;
import com.acgist.taoyao.media.signal.ITaoyao;
diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/SessionClient.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/SessionClient.java
index e090f22..0983a75 100644
--- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/SessionClient.java
+++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/SessionClient.java
@@ -4,17 +4,13 @@ import android.os.Handler;
import android.util.Log;
import com.acgist.taoyao.boot.model.Message;
-import com.acgist.taoyao.boot.utils.JSONUtils;
import com.acgist.taoyao.boot.utils.ListUtils;
import com.acgist.taoyao.boot.utils.MapUtils;
-import com.acgist.taoyao.media.VideoSourceType;
import com.acgist.taoyao.media.config.Config;
import com.acgist.taoyao.media.config.MediaProperties;
import com.acgist.taoyao.media.config.WebrtcProperties;
-import com.acgist.taoyao.media.config.WebrtcStunProperties;
import com.acgist.taoyao.media.signal.ITaoyao;
-import org.apache.commons.lang3.ArrayUtils;
import org.webrtc.DataChannel;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
@@ -24,11 +20,9 @@ import org.webrtc.PeerConnectionFactory;
import org.webrtc.SdpObserver;
import org.webrtc.SessionDescription;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
/**
diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/config/WebrtcProperties.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/config/WebrtcProperties.java
index c3bbe84..4e5c8ec 100644
--- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/config/WebrtcProperties.java
+++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/config/WebrtcProperties.java
@@ -6,9 +6,7 @@ import org.apache.commons.lang3.ArrayUtils;
import org.webrtc.PeerConnection;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* WebRTC配置
diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/signal/ITaoyao.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/signal/ITaoyao.java
index 72b85b4..a775e73 100644
--- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/signal/ITaoyao.java
+++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/signal/ITaoyao.java
@@ -4,8 +4,6 @@ import android.util.Log;
import com.acgist.taoyao.boot.model.Message;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Future;
import java.util.function.Consumer;
import java.util.function.Function;
diff --git a/taoyao-client-media/README.md b/taoyao-client-media/README.md
index 6427a7d..9568826 100644
--- a/taoyao-client-media/README.md
+++ b/taoyao-client-media/README.md
@@ -70,6 +70,10 @@ make -C worker
* [Medooze](https://github.com/medooze/media-server)
* [Mediasoup](https://github.com/versatica/mediasoup)
+## RTP裸流
+
+媒体服务主要使用`WebRTC`协议,同时支持接入`RTP`裸流,可以参考[RtpTest.java](../taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/rtp/RtpTest.java)配合`ffmpeg`使用`RTP`推拉流,具体代码需要自行实现。
+
## 协议
* https://www.ortc.org
diff --git a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/main/TaoyaoApplicationTests.java b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/main/TaoyaoApplicationTests.java
deleted file mode 100644
index 6264013..0000000
--- a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/main/TaoyaoApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.acgist.taoyao.main;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class TaoyaoApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
diff --git a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/SocketSignalTest.java b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/rtp/RtpTest.java
similarity index 98%
rename from taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/SocketSignalTest.java
rename to taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/rtp/RtpTest.java
index cda69b8..87edd73 100644
--- a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/SocketSignalTest.java
+++ b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/rtp/RtpTest.java
@@ -1,4 +1,4 @@
-package com.acgist.taoyao.signal;
+package com.acgist.taoyao.rtp;
import java.io.InputStream;
import java.io.OutputStream;
@@ -19,7 +19,7 @@ import com.acgist.taoyao.signal.utils.CipherUtils;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class SocketSignalTest {
+public class RtpTest {
@Test
void testSocket() throws Exception {
diff --git a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/service/Server.java b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/service/Server.java
deleted file mode 100644
index 030b2a7..0000000
--- a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/service/Server.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.acgist.taoyao.service;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-
-import org.junit.jupiter.api.Test;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-public class Server {
-
- public static final Executor EXECUTOR = Executors.newCachedThreadPool();
-
- @Test
- public void testServer() throws Exception {
- final ServerSocket server = new ServerSocket(9999);
- while(!server.isClosed()) {
- final Socket accept = server.accept();
- EXECUTOR.execute(() -> {
- try {
- this.execute(accept);
- } catch (IOException e) {
- log.error("异常", e);
- }
- });
- }
- server.close();
- }
-
- public void execute(Socket accept) throws IOException {
- final InputStream inputStream = accept.getInputStream();
- final OutputStream outputStream = accept.getOutputStream();
- while(!accept.isClosed()) {
- final byte[] bytes = new byte[1024];
- final int length = inputStream.read(bytes);
- log.info("收到消息:{}", new String(bytes, 0, length));
- outputStream.write(bytes, 0, length);
- outputStream.flush();
- }
- }
-
-}
diff --git a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/PlatformErrorProtocolTest.java b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/PlatformErrorProtocolTest.java
deleted file mode 100644
index a419218..0000000
--- a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/PlatformErrorProtocolTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.acgist.taoyao.signal;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import com.acgist.taoyao.annotation.TaoyaoTest;
-import com.acgist.taoyao.boot.model.MessageCodeException;
-import com.acgist.taoyao.main.TaoyaoApplication;
-import com.acgist.taoyao.signal.protocol.platform.PlatformErrorProtocol;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-@TaoyaoTest(classes = TaoyaoApplication.class)
-public class PlatformErrorProtocolTest {
-
- @Autowired
- private PlatformErrorProtocol platformErrorProtocol;
-
- @Test
- public void testException() {
- log.info("{}", this.platformErrorProtocol.build(MessageCodeException.of("自定义")));
- log.info("{}", this.platformErrorProtocol.build(new NullPointerException("空指针")));
- }
-
-}
diff --git a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketClient.java b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketClient.java
deleted file mode 100644
index a101cd7..0000000
--- a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketClient.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.acgist.taoyao.signal;
-
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.WebSocket;
-import java.net.http.WebSocket.Listener;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.concurrent.CompletionStage;
-import java.util.concurrent.CountDownLatch;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-public class WebSocketClient {
-
- public static final WebSocket build(String uri, String clientId) throws InterruptedException {
- return build(uri, clientId, null);
- }
-
- public static final WebSocket build(String uri, String clientId, CountDownLatch count) throws InterruptedException {
- final Object lock = new Object();
- try {
- return HttpClient
- .newBuilder()
- .sslContext(newSSLContext())
- .build()
- .newWebSocketBuilder()
- .buildAsync(URI.create(uri), new Listener() {
- @Override
- public void onOpen(WebSocket webSocket) {
- webSocket.sendText(String.format("""
- {"header":{"signal":"client::register","v":"1.0.0","id":"1"},"body":{"username":"taoyao","password":"taoyao","ip":"127.0.0.1","clientId":"%s"}}
- """, clientId), true);
- Listener.super.onOpen(webSocket);
- }
- @Override
- public CompletionStage> onText(WebSocket webSocket, CharSequence data, boolean last) {
- synchronized (lock) {
- lock.notifyAll();
- }
- if(count == null) {
- log.debug("收到WebSocket消息:{}", data);
- } else {
- count.countDown();
- log.debug("收到WebSocket消息:{}-{}", count.getCount(), data);
- }
- return Listener.super.onText(webSocket, data, last);
- }
- })
- .join();
- } finally {
- synchronized (lock) {
- lock.wait(1000);
- }
- }
- }
-
- private static final SSLContext newSSLContext() {
- SSLContext sslContext = null;
- try {
- // SSL协议:SSL、SSLv2、SSLv3、TLS、TLSv1、TLSv1.1、TLSv1.2、TLSv1.3
- sslContext = SSLContext.getInstance("TLSv1.2");
- sslContext.init(null, TRUST_ALL_CERT_MANAGER, new SecureRandom());
- } catch (KeyManagementException | NoSuchAlgorithmException e) {
- log.error("新建SSLContext异常", e);
- try {
- sslContext = SSLContext.getDefault();
- } catch (NoSuchAlgorithmException ex) {
- log.error("新建默认SSLContext异常", ex);
- }
- }
- return sslContext;
- }
-
- private static final TrustManager[] TRUST_ALL_CERT_MANAGER = new TrustManager[] {
- new X509TrustManager() {
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- }
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- }
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
- }
- };
-
-}
diff --git a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketSignalTest.java b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketSignalTest.java
deleted file mode 100644
index aa6af9a..0000000
--- a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketSignalTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.acgist.taoyao.signal;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.net.http.WebSocket;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-import org.junit.jupiter.api.Test;
-
-import com.acgist.taoyao.annotation.CostedTest;
-import com.acgist.taoyao.annotation.TaoyaoTest;
-import com.acgist.taoyao.main.TaoyaoApplication;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-@TaoyaoTest(classes = TaoyaoApplication.class)
-class WebSocketSignalTest {
-
- /**
- * 防止GC
- */
- private List list = new ArrayList<>();
-
- @Test
- void testSignal() throws InterruptedException {
- final WebSocket clientA = WebSocketClient.build("wss://localhost:8888/websocket.signal", "clientA");
- final WebSocket clientB = WebSocketClient.build("wss://localhost:8888/websocket.signal", "clientB");
- clientA.sendText("""
- {"header":{"signal":"client::heartbeat","v":"1.0.0","id":"1"},"body":{}}
- """, true).join();
- assertNotNull(clientA);
- assertNotNull(clientB);
- }
-
- @Test
- @CostedTest(thread = 10, count = 100, waitRelease = 5000L)
- void testThread() throws InterruptedException {
- final int total = 100;
- final CountDownLatch count = new CountDownLatch(total);
- final WebSocket clientA = WebSocketClient.build("wss://localhost:8888/websocket.signal", "clientA", count);
- final long aTime = System.currentTimeMillis();
- for (int index = 0; index < total; index++) {
- clientA.sendText("""
- {"header":{"signal":"client::status","v":"1.0.0","id":"1"},"body":{}}
- """, true).join();
- }
- this.list.add(clientA);
-// final ExecutorService executor = Executors.newFixedThreadPool(10);
-// for (int index = 0; index < total; index++) {
-// executor.execute(() -> {
-// synchronized (clientA) {
-// clientA.sendText("""
-// {"header":{"signal":"client::status","v":"1.0.0","id":"1"},"body":{}}
-// """, true).join();
-// }
-// });
-// }
- count.await();
- final long zTime = System.currentTimeMillis();
- log.info("执行时间:{}", zTime - aTime);
- log.info("当前连接数量:{}", this.list.size());
- assertNotNull(clientA);
- }
-
- @Test
- void testMax() throws InterruptedException {
- final int size = 1024;
- final CountDownLatch count = new CountDownLatch(size);
- for (int index = 0; index < size; index++) {
- final WebSocket clientA = WebSocketClient.build("wss://localhost:8888/websocket.signal", "clientA", count);
- assertNotNull(clientA);
- assertTrue(!(clientA.isInputClosed() || clientA.isOutputClosed()));
- }
- count.await();
- }
-
-}