[*] 日常优化
This commit is contained in:
@@ -1,282 +1,282 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>pom</packaging>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<url>https://gitee.com/acgist/taoyao</url>
|
||||
<name>taoyao</name>
|
||||
<description>桃夭:桃夭是套基于`Mediasoup`开发的`WebRTC`音视频信令服务,可以非常方便的扩展信令接入更多智能终端。</description>
|
||||
<inceptionYear>2022</inceptionYear>
|
||||
<url>https://gitee.com/acgist/taoyao</url>
|
||||
<name>taoyao</name>
|
||||
<description>桃夭:桃夭是套基于`Mediasoup`开发的`WebRTC`音视频信令服务,可以非常方便的扩展信令接入更多智能终端。</description>
|
||||
<inceptionYear>2022</inceptionYear>
|
||||
|
||||
<properties>
|
||||
<!-- 版本 -->
|
||||
<java.version>17</java.version>
|
||||
<lombok.version>1.18.28</lombok.version>
|
||||
<springdoc.version>2.1.0</springdoc.version>
|
||||
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
||||
<!-- 配置 -->
|
||||
<taoyao.maven.basedir>${project.basedir}</taoyao.maven.basedir>
|
||||
<taoyao.maven.encoding>UTF-8</taoyao.maven.encoding>
|
||||
<taoyao.maven.skip.assembly>true</taoyao.maven.skip.assembly>
|
||||
</properties>
|
||||
<properties>
|
||||
<!-- 版本 -->
|
||||
<java.version>17</java.version>
|
||||
<lombok.version>1.18.28</lombok.version>
|
||||
<springdoc.version>2.1.0</springdoc.version>
|
||||
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
||||
<!-- 配置 -->
|
||||
<taoyao.maven.basedir>${project.basedir}</taoyao.maven.basedir>
|
||||
<taoyao.maven.encoding>UTF-8</taoyao.maven.encoding>
|
||||
<taoyao.maven.skip.assembly>true</taoyao.maven.skip.assembly>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>taoyao-boot</module>
|
||||
<module>taoyao-signal</module>
|
||||
<module>taoyao-server</module>
|
||||
</modules>
|
||||
<modules>
|
||||
<module>taoyao-boot</module>
|
||||
<module>taoyao-signal</module>
|
||||
<module>taoyao-server</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<!-- 快速开发 -->
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<!-- 开发工具 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<!-- Jackson -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
<!-- 接口文档 -->
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
</dependency>
|
||||
<!-- AOP -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<!-- 日志框架 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</dependency>
|
||||
<dependencies>
|
||||
<!-- 快速开发 -->
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<!-- 开发工具 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<!-- Jackson -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
<!-- 接口文档 -->
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
</dependency>
|
||||
<!-- AOP -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<!-- 日志框架 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 单元测试 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!-- 单元测试 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao-boot</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao-signal</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- mapstruct -->
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao-boot</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao-signal</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- mapstruct -->
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.yml</include>
|
||||
<include>**/*.properties</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<!-- 匹配所有文件:**/* -->
|
||||
<!-- 匹配所有带有后缀文件:**/*.* -->
|
||||
<include>**/*.*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.yml</exclude>
|
||||
<exclude>**/*.properties</exclude>
|
||||
</excludes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.yml</include>
|
||||
<include>**/*.properties</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<!-- 匹配所有文件:**/* -->
|
||||
<!-- 匹配所有带有后缀文件:**/*.* -->
|
||||
<include>**/*.*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.yml</exclude>
|
||||
<exclude>**/*.properties</exclude>
|
||||
</excludes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${taoyao.maven.encoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- Jar配置独立config目录 -->
|
||||
<excludes>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${taoyao.maven.encoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- Jar配置独立config目录 -->
|
||||
<excludes>
|
||||
<include>*.cer</include>
|
||||
<include>*.jks</include>
|
||||
<include>*.p12</include>
|
||||
<include>*.pfx</include>
|
||||
<exclude>*.yml</exclude>
|
||||
<exclude>*.properties</exclude>
|
||||
</excludes>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<!-- 配置文件 -->
|
||||
<Class-Path>../config/</Class-Path>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<attach>false</attach>
|
||||
<skipAssembly>${taoyao.maven.skip.assembly}</skipAssembly>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
<exclude>*.yml</exclude>
|
||||
<exclude>*.properties</exclude>
|
||||
</excludes>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<!-- 配置文件 -->
|
||||
<Class-Path>../config/</Class-Path>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<attach>false</attach>
|
||||
<skipAssembly>${taoyao.maven.skip.assembly}</skipAssembly>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<profile>dev</profile>
|
||||
<taoyao.maven.jvm.arg></taoyao.maven.jvm.arg>
|
||||
<taoyao.maven.jvm.mem>-Xms512M -Xmx1024M -XX:NewRatio=1 -XX:SurvivorRatio=2</taoyao.maven.jvm.mem>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>${taoyao.maven.basedir}/docs/assembly/dev.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>prd</id>
|
||||
<properties>
|
||||
<profile>prd</profile>
|
||||
<taoyao.maven.jvm.arg></taoyao.maven.jvm.arg>
|
||||
<taoyao.maven.jvm.mem>-Xms2048M -Xmx4096M -XX:NewRatio=1 -XX:SurvivorRatio=2</taoyao.maven.jvm.mem>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>${taoyao.maven.basedir}/docs/assembly/prd.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<profile>dev</profile>
|
||||
<taoyao.maven.jvm.arg></taoyao.maven.jvm.arg>
|
||||
<taoyao.maven.jvm.mem>-Xms512M -Xmx1024M -XX:NewRatio=1 -XX:SurvivorRatio=2</taoyao.maven.jvm.mem>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>${taoyao.maven.basedir}/docs/assembly/dev.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>prd</id>
|
||||
<properties>
|
||||
<profile>prd</profile>
|
||||
<taoyao.maven.jvm.arg></taoyao.maven.jvm.arg>
|
||||
<taoyao.maven.jvm.mem>-Xms2048M -Xmx4096M -XX:NewRatio=1 -XX:SurvivorRatio=2</taoyao.maven.jvm.mem>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>${taoyao.maven.basedir}/docs/assembly/prd.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
@@ -118,8 +118,11 @@ public final class NetUtils {
|
||||
final InetAddress clientAddress = NetUtils.realAddress(clientIP);
|
||||
final boolean sourceLocal = NetUtils.localAddress(sourceAddress);
|
||||
final boolean clientLocal = NetUtils.localAddress(clientAddress);
|
||||
// 内网服务 && 内网设备
|
||||
// 内网服务 && 内网设备 => 重写服务地址
|
||||
if(sourceLocal && clientLocal) {
|
||||
if(NetUtils.subnetIP(sourceIP, clientIP)) {
|
||||
return sourceIP;
|
||||
}
|
||||
final RewriteRuleProperties rule = NetUtils.rewriteProperties.getRule().stream()
|
||||
.filter(v -> NetUtils.subnetIP(v.getNetwork(), clientIP))
|
||||
.findFirst()
|
||||
@@ -127,11 +130,10 @@ public final class NetUtils {
|
||||
if(rule == null) {
|
||||
return sourceIP;
|
||||
}
|
||||
log.debug("地址重写:{} - {} - {}", sourceIP, clientIP, rule.getNetwork());
|
||||
// 明确配置
|
||||
if(StringUtils.isNotEmpty(rule.getInnerHost())) {
|
||||
return rule.getInnerHost();
|
||||
}
|
||||
log.debug("地址重写:{} - {} - {}", sourceIP, clientIP, rule.getNetwork());
|
||||
// 地址 = 网络号 + 主机号
|
||||
final byte[] sourceBytes = sourceAddress.getAddress();
|
||||
final byte[] clientBytes = clientAddress.getAddress();
|
||||
@@ -151,7 +153,7 @@ public final class NetUtils {
|
||||
return InetAddress.getByAddress(bytes).getHostAddress();
|
||||
}
|
||||
}
|
||||
// 内网服务 && 公网设备
|
||||
// 内网服务 && 公网设备 => 公网服务地址
|
||||
if(sourceLocal && !clientLocal) {
|
||||
final RewriteRuleProperties rule = NetUtils.rewriteProperties.getRule().stream()
|
||||
.filter(v -> NetUtils.subnetIP(v.getNetwork(), sourceIP))
|
||||
@@ -164,7 +166,7 @@ public final class NetUtils {
|
||||
return rule.getOuterHost();
|
||||
}
|
||||
}
|
||||
// 公网服务 && 内网设备
|
||||
// 公网服务 && 内网设备 => 内网服务地址
|
||||
if(!sourceLocal && clientLocal) {
|
||||
final RewriteRuleProperties rule = NetUtils.rewriteProperties.getRule().stream()
|
||||
.filter(v -> NetUtils.subnetIP(v.getNetwork(), clientIP))
|
||||
|
||||
@@ -2,52 +2,52 @@
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<parent>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>taoyao-server</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>taoyao-server</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>taoyao-server</name>
|
||||
<description>启动服务</description>
|
||||
<name>taoyao-server</name>
|
||||
<description>启动服务</description>
|
||||
|
||||
<properties>
|
||||
<taoyao.maven.basedir>${project.parent.basedir}</taoyao.maven.basedir>
|
||||
<taoyao.maven.skip.assembly>false</taoyao.maven.skip.assembly>
|
||||
</properties>
|
||||
<properties>
|
||||
<taoyao.maven.basedir>${project.parent.basedir}</taoyao.maven.basedir>
|
||||
<taoyao.maven.skip.assembly>false</taoyao.maven.skip.assembly>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao-signal</artifactId>
|
||||
</dependency>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.acgist</groupId>
|
||||
<artifactId>taoyao-signal</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.acgist.taoyao.main.TaoyaoApplication</mainClass>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>./</classpathPrefix>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.acgist.taoyao.main.TaoyaoApplication</mainClass>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>./</classpathPrefix>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -22,29 +22,29 @@ import com.acgist.taoyao.signal.service.impl.SecurityServiceImpl;
|
||||
@AutoConfiguration
|
||||
public class TaoyaoAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SlowInterceptor slowInterceptor(TaoyaoProperties taoyaoProperties) {
|
||||
return new SlowInterceptor(taoyaoProperties);
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SlowInterceptor slowInterceptor(TaoyaoProperties taoyaoProperties) {
|
||||
return new SlowInterceptor(taoyaoProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SecurityService securityService(
|
||||
SecurityProperties securityProperties,
|
||||
@Autowired(required = true) SecurityProperties securityProperties,
|
||||
@Autowired(required = false) UsernamePasswordService usernamePasswordService
|
||||
) {
|
||||
return new SecurityServiceImpl(securityProperties, usernamePasswordService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "taoyao.security", name = "enabled", havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnMissingBean
|
||||
public SecurityInterceptor securityInterceptor(
|
||||
SecurityService securityService,
|
||||
SecurityProperties securityProperties
|
||||
) {
|
||||
return new SecurityInterceptor(securityService, securityProperties);
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "taoyao.security", name = "enabled", havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnMissingBean
|
||||
public SecurityInterceptor securityInterceptor(
|
||||
SecurityService securityService,
|
||||
SecurityProperties securityProperties
|
||||
) {
|
||||
return new SecurityInterceptor(securityService, securityProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.acgist.taoyao.boot.config.FfmpegProperties;
|
||||
import com.acgist.taoyao.boot.config.RewriteProperties;
|
||||
import com.acgist.taoyao.boot.config.MediaProperties;
|
||||
import com.acgist.taoyao.boot.config.RewriteProperties;
|
||||
import com.acgist.taoyao.boot.config.SocketProperties;
|
||||
import com.acgist.taoyao.boot.config.WebrtcProperties;
|
||||
import com.acgist.taoyao.boot.model.Message;
|
||||
@@ -29,18 +29,18 @@ import lombok.RequiredArgsConstructor;
|
||||
@RequiredArgsConstructor
|
||||
public class ConfigController {
|
||||
|
||||
private final MediaProperties mediaProperties;
|
||||
private final FfmpegProperties ffmpegProperties;
|
||||
private final SocketProperties socketProperties;
|
||||
private final WebrtcProperties webrtcProperties;
|
||||
private final RewriteProperties rewriteProperties;
|
||||
private final MediaProperties mediaProperties;
|
||||
private final FfmpegProperties ffmpegProperties;
|
||||
private final SocketProperties socketProperties;
|
||||
private final WebrtcProperties webrtcProperties;
|
||||
private final RewriteProperties rewriteProperties;
|
||||
|
||||
@Operation(summary = "媒体配置", description = "媒体配置")
|
||||
@GetMapping("/media")
|
||||
@ApiResponse(content = @Content(schema = @Schema(implementation = MediaProperties.class)))
|
||||
public Message media() {
|
||||
return Message.success(this.mediaProperties);
|
||||
}
|
||||
@GetMapping("/media")
|
||||
@ApiResponse(content = @Content(schema = @Schema(implementation = MediaProperties.class)))
|
||||
public Message media() {
|
||||
return Message.success(this.mediaProperties);
|
||||
}
|
||||
|
||||
@Operation(summary = "FFmpeg配置", description = "FFmpeg配置")
|
||||
@GetMapping("/ffmpeg")
|
||||
@@ -56,18 +56,18 @@ public class ConfigController {
|
||||
return Message.success(this.socketProperties);
|
||||
}
|
||||
|
||||
@Operation(summary = "WebRTC配置", description = "WebRTC配置")
|
||||
@GetMapping("/webrtc")
|
||||
@ApiResponse(content = @Content(schema = @Schema(implementation = WebrtcProperties.class)))
|
||||
public Message webrtc() {
|
||||
return Message.success(this.webrtcProperties);
|
||||
}
|
||||
@Operation(summary = "WebRTC配置", description = "WebRTC配置")
|
||||
@GetMapping("/webrtc")
|
||||
@ApiResponse(content = @Content(schema = @Schema(implementation = WebrtcProperties.class)))
|
||||
public Message webrtc() {
|
||||
return Message.success(this.webrtcProperties);
|
||||
}
|
||||
|
||||
@Operation(summary = "地址重写配置", description = "地址重写配置")
|
||||
@GetMapping("/rewrite")
|
||||
@ApiResponse(content = @Content(schema = @Schema(implementation = WebrtcProperties.class)))
|
||||
public Message rewrite() {
|
||||
return Message.success(this.rewriteProperties);
|
||||
}
|
||||
@Operation(summary = "地址重写配置", description = "地址重写配置")
|
||||
@GetMapping("/rewrite")
|
||||
@ApiResponse(content = @Content(schema = @Schema(implementation = WebrtcProperties.class)))
|
||||
public Message rewrite() {
|
||||
return Message.success(this.rewriteProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.acgist.taoyao.signal.protocol.control.IControlPhotographProtocol;
|
||||
import com.acgist.taoyao.signal.protocol.control.IControlServerRecordProtocol;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@@ -34,31 +35,22 @@ import lombok.RequiredArgsConstructor;
|
||||
@RequiredArgsConstructor
|
||||
public class ControlController {
|
||||
|
||||
private final IControlBellProtocol controlBellProtocol;
|
||||
private final IControlPhotographProtocol controlPhotographProtocol;
|
||||
private final IControlConfigAudioProtocol controlConfigAudioProtocol;
|
||||
private final IControlConfigVideoProtocol controlConfigVideoProtocol;
|
||||
private final IControlBellProtocol controlBellProtocol;
|
||||
private final IControlPhotographProtocol controlPhotographProtocol;
|
||||
private final IControlConfigAudioProtocol controlConfigAudioProtocol;
|
||||
private final IControlConfigVideoProtocol controlConfigVideoProtocol;
|
||||
private final IControlClientRecordProtocol controlClientRecordProtocol;
|
||||
private final IControlServerRecordProtocol controlServerRecordProtocol;
|
||||
|
||||
@Operation(summary = "响铃", description = "响铃控制")
|
||||
@GetMapping("/bell/{clientId}")
|
||||
public Message bell(@PathVariable String clientId, @NotNull(message = "没有指定操作状态") Boolean enabled) {
|
||||
public Message bell(
|
||||
@PathVariable String clientId,
|
||||
@NotNull(message = "没有指定操作状态") Boolean enabled
|
||||
) {
|
||||
return this.controlBellProtocol.execute(clientId, enabled);
|
||||
}
|
||||
|
||||
@Operation(summary = "录像", description = "终端录像控制")
|
||||
@GetMapping("/client/record/{clientId}")
|
||||
public Message record(@PathVariable String clientId, @NotNull(message = "没有指定操作状态") Boolean enabled) {
|
||||
return this.controlClientRecordProtocol.execute(clientId, enabled);
|
||||
}
|
||||
|
||||
@Operation(summary = "录像", description = "服务端录像控制")
|
||||
@GetMapping("/server/record/{roomId}/{clientId}")
|
||||
public Message record(@PathVariable String roomId, @PathVariable String clientId, @NotNull(message = "没有指定操作状态") Boolean enabled) {
|
||||
return this.controlServerRecordProtocol.execute(roomId, clientId, enabled);
|
||||
}
|
||||
|
||||
@Operation(summary = "拍照", description = "拍照控制")
|
||||
@GetMapping("/photograph/{clientId}")
|
||||
public Message photograph(@PathVariable String clientId) {
|
||||
@@ -67,14 +59,39 @@ public class ControlController {
|
||||
|
||||
@Operation(summary = "配置音频", description = "配置音频")
|
||||
@GetMapping("/config/audio/{clientId}")
|
||||
public Message configAudio(@PathVariable String clientId, @Valid MediaAudioProperties mediaAudioProperties) {
|
||||
public Message configAudio(
|
||||
@PathVariable String clientId,
|
||||
@Valid @RequestBody MediaAudioProperties mediaAudioProperties
|
||||
) {
|
||||
return this.controlConfigAudioProtocol.execute(clientId, mediaAudioProperties);
|
||||
}
|
||||
|
||||
@Operation(summary = "配置视频", description = "配置视频")
|
||||
@GetMapping("/config/video/{clientId}")
|
||||
public Message configVideo(@PathVariable String clientId, @Valid MediaVideoProperties mediaVideoProperties) {
|
||||
public Message configVideo(
|
||||
@PathVariable String clientId,
|
||||
@Valid @RequestBody MediaVideoProperties mediaVideoProperties
|
||||
) {
|
||||
return this.controlConfigVideoProtocol.execute(clientId, mediaVideoProperties);
|
||||
}
|
||||
|
||||
@Operation(summary = "录像", description = "终端录像控制")
|
||||
@GetMapping("/client/record/{clientId}")
|
||||
public Message record(
|
||||
@PathVariable String clientId,
|
||||
@NotNull(message = "没有指定操作状态") Boolean enabled
|
||||
) {
|
||||
return this.controlClientRecordProtocol.execute(clientId, enabled);
|
||||
}
|
||||
|
||||
@Operation(summary = "录像", description = "服务端录像控制")
|
||||
@GetMapping("/server/record/{roomId}/{clientId}")
|
||||
public Message record(
|
||||
@PathVariable String roomId,
|
||||
@PathVariable String clientId,
|
||||
@NotNull(message = "没有指定操作状态") Boolean enabled
|
||||
) {
|
||||
return this.controlServerRecordProtocol.execute(roomId, clientId, enabled);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,14 +25,14 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@RequestMapping("/platform")
|
||||
public class PlatformController {
|
||||
|
||||
private final PlatformRebootProtocol platformRebootProtocol;
|
||||
private final PlatformRebootProtocol platformRebootProtocol;
|
||||
private final PlatformShutdownProtocol platformShutdownProtocol;
|
||||
|
||||
public PlatformController(
|
||||
@Autowired(required = false) PlatformRebootProtocol platformRebootProtocol,
|
||||
@Autowired(required = false) PlatformRebootProtocol platformRebootProtocol,
|
||||
@Autowired(required = false) PlatformShutdownProtocol platformShutdownProtocol
|
||||
) {
|
||||
this.platformRebootProtocol = platformRebootProtocol;
|
||||
this.platformRebootProtocol = platformRebootProtocol;
|
||||
this.platformShutdownProtocol = platformShutdownProtocol;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,14 +25,14 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@RequestMapping("/system")
|
||||
public class SystemController {
|
||||
|
||||
private final SystemRebootProtocol systemRebootProtocol;
|
||||
private final SystemRebootProtocol systemRebootProtocol;
|
||||
private final SystemShutdownProtocol systemShutdownProtocol;
|
||||
|
||||
public SystemController(
|
||||
@Autowired(required = false) SystemRebootProtocol systemRebootProtocol,
|
||||
@Autowired(required = false) SystemRebootProtocol systemRebootProtocol,
|
||||
@Autowired(required = false) SystemShutdownProtocol systemShutdownProtocol
|
||||
) {
|
||||
this.systemRebootProtocol = systemRebootProtocol;
|
||||
this.systemRebootProtocol = systemRebootProtocol;
|
||||
this.systemShutdownProtocol = systemShutdownProtocol;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,19 +24,22 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class SecurityInterceptor extends InterceptorAdapter {
|
||||
|
||||
private final SecurityService securityService;
|
||||
private final SecurityProperties securityProperties;
|
||||
private final SecurityService securityService;
|
||||
private final SecurityProperties securityProperties;
|
||||
|
||||
/**
|
||||
* 鉴权信息
|
||||
*/
|
||||
private final String authenticate;
|
||||
/**
|
||||
* 地址匹配
|
||||
*/
|
||||
private final AntPathMatcher matcher;
|
||||
/**
|
||||
* 鉴权信息
|
||||
*/
|
||||
private final String authenticate;
|
||||
/**
|
||||
* 地址匹配
|
||||
*/
|
||||
private final AntPathMatcher matcher;
|
||||
|
||||
public SecurityInterceptor(SecurityService securityService, SecurityProperties securityProperties) {
|
||||
public SecurityInterceptor(
|
||||
SecurityService securityService,
|
||||
SecurityProperties securityProperties
|
||||
) {
|
||||
this.securityService = securityService;
|
||||
this.securityProperties = securityProperties;
|
||||
this.authenticate = "Basic Realm=\"" + this.securityProperties.getRealm() + "\"";
|
||||
@@ -44,76 +47,76 @@ public class SecurityInterceptor extends InterceptorAdapter {
|
||||
log.info("安全拦截密码:{}", securityProperties.getPassword());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "安全拦截器";
|
||||
}
|
||||
@Override
|
||||
public String name() {
|
||||
return "安全拦截器";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] pathPattern() {
|
||||
return new String[] { "/**" };
|
||||
}
|
||||
@Override
|
||||
public String[] pathPattern() {
|
||||
return new String[] { "/**" };
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Integer.MIN_VALUE + 1;
|
||||
}
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Integer.MIN_VALUE + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
if(this.permit(request) || this.authorization(request)) {
|
||||
return true;
|
||||
}
|
||||
if(log.isDebugEnabled()) {
|
||||
log.debug("授权失败:{}", request.getRequestURL());
|
||||
}
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, this.authenticate);
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
if(this.permit(request) || this.authorization(request)) {
|
||||
return true;
|
||||
}
|
||||
if(log.isDebugEnabled()) {
|
||||
log.debug("授权失败:{}", request.getRequestURL());
|
||||
}
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, this.authenticate);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param request 请求
|
||||
*
|
||||
* @return 是否许可请求
|
||||
*/
|
||||
private boolean permit(HttpServletRequest request) {
|
||||
final String uri = request.getRequestURI();
|
||||
final String[] permit = this.securityProperties.getPermit();
|
||||
if(ArrayUtils.isEmpty(permit)) {
|
||||
return false;
|
||||
}
|
||||
for (String pattern : permit) {
|
||||
if(this.matcher.match(pattern, uri)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @param request 请求
|
||||
*
|
||||
* @return 是否许可请求
|
||||
*/
|
||||
private boolean permit(HttpServletRequest request) {
|
||||
final String uri = request.getRequestURI();
|
||||
final String[] permit = this.securityProperties.getPermit();
|
||||
if(ArrayUtils.isEmpty(permit)) {
|
||||
return false;
|
||||
}
|
||||
for (String pattern : permit) {
|
||||
if(this.matcher.match(pattern, uri)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param request 请求
|
||||
*
|
||||
* @return 是否授权成功
|
||||
*/
|
||||
private boolean authorization(HttpServletRequest request) {
|
||||
String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
if(StringUtils.isEmpty(authorization)) {
|
||||
return false;
|
||||
}
|
||||
int index = authorization.indexOf(' ');
|
||||
if(index < 0) {
|
||||
return false;
|
||||
}
|
||||
authorization = authorization.substring(index + 1).strip();
|
||||
authorization = new String(Base64.getMimeDecoder().decode(authorization));
|
||||
index = authorization.indexOf(':');
|
||||
if(index < 0) {
|
||||
return false;
|
||||
}
|
||||
final String username = authorization.substring(0, index);
|
||||
final String password = authorization.substring(index + 1);
|
||||
return this.securityService.authenticate(username, password);
|
||||
}
|
||||
/**
|
||||
* @param request 请求
|
||||
*
|
||||
* @return 是否授权成功
|
||||
*/
|
||||
private boolean authorization(HttpServletRequest request) {
|
||||
String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
if(StringUtils.isEmpty(authorization)) {
|
||||
return false;
|
||||
}
|
||||
int index = authorization.indexOf(' ');
|
||||
if(index < 0) {
|
||||
return false;
|
||||
}
|
||||
authorization = authorization.substring(index + 1).strip();
|
||||
authorization = new String(Base64.getMimeDecoder().decode(authorization));
|
||||
index = authorization.indexOf(':');
|
||||
if(index < 0) {
|
||||
return false;
|
||||
}
|
||||
final String username = authorization.substring(0, index);
|
||||
final String password = authorization.substring(index + 1);
|
||||
return this.securityService.authenticate(username, password);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,47 +15,46 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class SlowInterceptor extends InterceptorAdapter {
|
||||
|
||||
private final TaoyaoProperties taoyaoProperties;
|
||||
private final TaoyaoProperties taoyaoProperties;
|
||||
|
||||
/**
|
||||
* 请求开始时间
|
||||
*/
|
||||
private final ThreadLocal<Long> local;
|
||||
/**
|
||||
* 请求开始时间
|
||||
*/
|
||||
private final ThreadLocal<Long> local;
|
||||
|
||||
public SlowInterceptor(TaoyaoProperties taoyaoProperties) {
|
||||
public SlowInterceptor(TaoyaoProperties taoyaoProperties) {
|
||||
this.taoyaoProperties = taoyaoProperties;
|
||||
this.local = new ThreadLocal<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "过慢请求拦截器";
|
||||
}
|
||||
@Override
|
||||
public String name() {
|
||||
return "过慢请求拦截器";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] pathPattern() {
|
||||
return new String[] { "/**" };
|
||||
}
|
||||
@Override
|
||||
public String[] pathPattern() {
|
||||
return new String[] { "/**" };
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
this.local.set(System.currentTimeMillis());
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
this.local.set(System.currentTimeMillis());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) throws Exception {
|
||||
final long duration;
|
||||
final Long last = this.local.get();
|
||||
if(last != null && (duration = System.currentTimeMillis() - last) > this.taoyaoProperties.getTimeout()) {
|
||||
log.info("请求执行时间过慢:{} - {}", request.getRequestURI(), duration);
|
||||
}
|
||||
this.local.remove();
|
||||
}
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) throws Exception {
|
||||
final long duration = System.currentTimeMillis() - this.local.get();
|
||||
if(duration > this.taoyaoProperties.getTimeout()) {
|
||||
log.info("请求执行时间过慢:{} - {}", request.getRequestURI(), duration);
|
||||
}
|
||||
this.local.remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
@SpringBootApplication
|
||||
public class TaoyaoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TaoyaoApplication.class, args);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TaoyaoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>桃夭信令服务</title>
|
||||
<style type="text/css">
|
||||
p{text-align:center;}
|
||||
a{text-decoration:none;}
|
||||
</style>
|
||||
<meta charset="UTF-8">
|
||||
<title>桃夭信令服务</title>
|
||||
<style type="text/css">
|
||||
p{text-align:center;}
|
||||
a{text-decoration:none;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p><a href="https://gitee.com/acgist/taoyao">taoyao-signal-server</a></p>
|
||||
<p><a href="https://www.acgist.com">acgist</a></p>
|
||||
<p><a href="https://gitee.com/acgist/taoyao">taoyao-signal-server</a></p>
|
||||
<p><a href="https://www.acgist.com">acgist</a></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -19,29 +19,29 @@ import java.util.concurrent.TimeUnit;
|
||||
@Documented
|
||||
public @interface CostedTest {
|
||||
|
||||
/**
|
||||
* @return 执行次数
|
||||
*/
|
||||
int count() default 1;
|
||||
/**
|
||||
* @return 执行次数
|
||||
*/
|
||||
int count() default 1;
|
||||
|
||||
/**
|
||||
* @return 线程数量
|
||||
*/
|
||||
int thread() default 1;
|
||||
/**
|
||||
* @return 线程数量
|
||||
*/
|
||||
int thread() default 1;
|
||||
|
||||
/**
|
||||
* @return 超时时间
|
||||
*/
|
||||
long timeout() default 1000L;
|
||||
/**
|
||||
* @return 超时时间
|
||||
*/
|
||||
long timeout() default 1000L;
|
||||
|
||||
/**
|
||||
* @return 等待资源释放时间
|
||||
*/
|
||||
long waitRelease() default 0L;
|
||||
/**
|
||||
* @return 等待资源释放时间
|
||||
*/
|
||||
long waitRelease() default 0L;
|
||||
|
||||
/**
|
||||
* @return 超时时间单位
|
||||
*/
|
||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
|
||||
/**
|
||||
* @return 超时时间单位
|
||||
*/
|
||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
|
||||
|
||||
}
|
||||
|
||||
@@ -19,45 +19,45 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
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();
|
||||
final TimeUnit timeUnit = costedTest.timeUnit();
|
||||
final long aTime = System.currentTimeMillis();
|
||||
if(thread == 1) {
|
||||
for (int index = 0; index < count; index++) {
|
||||
testContext.getTestMethod().invoke(testContext.getTestInstance());
|
||||
}
|
||||
} else {
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(count);
|
||||
final ExecutorService executor = Executors.newFixedThreadPool(thread);
|
||||
for (int index = 0; index < count; index++) {
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
testContext.getTestMethod().invoke(testContext.getTestInstance());
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
log.error("多线程测试异常", e);
|
||||
} finally {
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
countDownLatch.await(timeout, timeUnit);
|
||||
executor.shutdown();
|
||||
}
|
||||
final long zTime = System.currentTimeMillis();
|
||||
final long costed = zTime - aTime;
|
||||
log.info("多线程测试消耗时间:{}", costed);
|
||||
final long waitRelease = costedTest.waitRelease();
|
||||
if(waitRelease > 0) {
|
||||
Thread.sleep(waitRelease);
|
||||
}
|
||||
}
|
||||
@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();
|
||||
final TimeUnit timeUnit = costedTest.timeUnit();
|
||||
final long aTime = System.currentTimeMillis();
|
||||
if(thread == 1) {
|
||||
for (int index = 0; index < count; index++) {
|
||||
testContext.getTestMethod().invoke(testContext.getTestInstance());
|
||||
}
|
||||
} else {
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(count);
|
||||
final ExecutorService executor = Executors.newFixedThreadPool(thread);
|
||||
for (int index = 0; index < count; index++) {
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
testContext.getTestMethod().invoke(testContext.getTestInstance());
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
log.error("多线程测试异常", e);
|
||||
} finally {
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
countDownLatch.await(timeout, timeUnit);
|
||||
executor.shutdown();
|
||||
}
|
||||
final long zTime = System.currentTimeMillis();
|
||||
final long costed = zTime - aTime;
|
||||
log.info("多线程测试消耗时间:{}", costed);
|
||||
final long waitRelease = costedTest.waitRelease();
|
||||
if(waitRelease > 0) {
|
||||
Thread.sleep(waitRelease);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.test.context.TestExecutionListeners.MergeMode;
|
||||
@TestExecutionListeners(listeners = CostedTestTestExecutionListener.class, mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
|
||||
public @interface TaoyaoTest {
|
||||
|
||||
@AliasFor(annotation = SpringBootTest.class)
|
||||
Class<?>[] classes() default {};
|
||||
@AliasFor(annotation = SpringBootTest.class)
|
||||
Class<?>[] classes() default {};
|
||||
|
||||
}
|
||||
|
||||
@@ -21,99 +21,99 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class RtpTest {
|
||||
|
||||
@Test
|
||||
void testSocket() throws Exception {
|
||||
final Socket socket = new Socket();
|
||||
socket.connect(new InetSocketAddress("127.0.0.1", 9999));
|
||||
final InputStream inputStream = socket.getInputStream();
|
||||
final OutputStream outputStream = socket.getOutputStream();
|
||||
// 随机密码:https://localhost:8888/config/socket
|
||||
final String secret = "TSFXzB7hcfE=".strip();
|
||||
final Cipher encrypt = CipherUtils.buildCipher(Cipher.ENCRYPT_MODE, Encrypt.DES, secret);
|
||||
final Cipher decrypt = CipherUtils.buildCipher(Cipher.DECRYPT_MODE, Encrypt.DES, secret);
|
||||
// 接收
|
||||
new Thread(() -> {
|
||||
int length = 0;
|
||||
short messageLength = 0;
|
||||
final byte[] bytes = new byte[1024];
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
|
||||
try {
|
||||
while((length = inputStream.read(bytes)) >= 0) {
|
||||
buffer.put(bytes, 0, length);
|
||||
while(buffer.position() > 0) {
|
||||
if(messageLength <= 0) {
|
||||
if(buffer.position() < Short.BYTES) {
|
||||
// 不够消息长度
|
||||
break;
|
||||
} else {
|
||||
buffer.flip();
|
||||
messageLength = buffer.getShort();
|
||||
buffer.compact();
|
||||
if(messageLength > 16 * 1024) {
|
||||
throw MessageCodeException.of("超过最大数据大小:" + messageLength);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(buffer.position() < messageLength) {
|
||||
// 不够消息长度
|
||||
break;
|
||||
} else {
|
||||
final byte[] message = new byte[messageLength];
|
||||
messageLength = 0;
|
||||
buffer.flip();
|
||||
buffer.get(message);
|
||||
buffer.compact();
|
||||
log.debug("收到消息:{}", new String(decrypt.doFinal(message)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("读取异常", e);
|
||||
}
|
||||
}).start();
|
||||
// 发送
|
||||
String line = """
|
||||
{
|
||||
"header":{"v":"1.0.0","id":1215293599999001,"signal":"client::register"},
|
||||
"body":{"clientId":"ffmpeg","name":"ffmpeg","clientType":"WEB","battery":100,"charging":true,"username":"taoyao","password":"taoyao"}
|
||||
}
|
||||
""";
|
||||
// {"header":{"v":"1.0.0","id":1215310510002009,"signal":"room::enter"},"body":{"roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9"}}
|
||||
// {"header":{"v":"1.0.0","id":1215310510002010,"signal":"media::transport::plain"},"body":{"roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9","rtcpMux":false,"comedia":true}}
|
||||
// {"header":{"v":"1.0.0","id":1215375110006012,"signal":"media::produce"},"body":{"kind":"video","roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9","transportId":"14dc9307-bf9c-4442-a9ad-ce6a97623ef4","appData":{},"rtpParameters":{"codecs":[{"mimeType":"video/vp8","clockRate":90000,"payloadType":102,"rtcpFeedback":[]}],"encodings":[{"ssrc":123123}]}}}
|
||||
// 音频转为PCM
|
||||
// ffmpeg.exe -i .\a.m4a -f s16le a.pcm
|
||||
// ffmpeg.exe -i .\a.m4a -f s16le -ac 2 -ar 8000 a.pcm
|
||||
// ffplay.exe -ar 48000 -ac 2 -f s16le -i a.pcm
|
||||
// ffmpeg不支持rtcpMux
|
||||
// ffmpeg -re -i video.mp4 -c:v vp8 -map 0:0 -f tee "[select=v:f=rtp:ssrc=123123:payload_type=102]rtp://192.168.1.110:40793?rtcpport=47218"
|
||||
// ffmpeg -re -i video.mp4 -c:v libvpx -map 0:0 -f tee "[select=v:f=rtp:ssrc=123123:payload_type=102]rtp://192.168.1.110:40793?rtcpport=47218"
|
||||
// 音频视频同时传输
|
||||
// ffmpeg -re -i video.mp4 -c:a libopus -vn -f rtp rtp://192.168.1.110:8888 -c:v libx264 -an -f rtp rtp://192.168.1.110:9999 -sdp_file taoyao.sdp
|
||||
// ffplay -protocol_whitelist "file,rtp,udp" -i taoyao.sdp
|
||||
// ffmpeg -protocol_whitelist "file,rtp,udp" -i taoyao.sdp taoyao.mp4
|
||||
final Scanner scanner = new Scanner(System.in);
|
||||
do {
|
||||
if(StringUtils.isEmpty(line)) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
final byte[] bytes = line.getBytes();
|
||||
final byte[] encryptBytes = encrypt.doFinal(bytes);
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(Short.BYTES + encryptBytes.length);
|
||||
buffer.putShort((short) encryptBytes.length);
|
||||
buffer.put(encryptBytes);
|
||||
buffer.flip();
|
||||
final byte[] message = new byte[buffer.capacity()];
|
||||
buffer.get(message);
|
||||
outputStream.write(message);
|
||||
} catch (Exception e) {
|
||||
log.error("发送异常", e);
|
||||
}
|
||||
} while((line = scanner.next()) != null);
|
||||
socket.close();
|
||||
scanner.close();
|
||||
}
|
||||
@Test
|
||||
void testSocket() throws Exception {
|
||||
final Socket socket = new Socket();
|
||||
socket.connect(new InetSocketAddress("127.0.0.1", 9999));
|
||||
final InputStream inputStream = socket.getInputStream();
|
||||
final OutputStream outputStream = socket.getOutputStream();
|
||||
// 随机密码:https://localhost:8888/config/socket
|
||||
final String secret = "TSFXzB7hcfE=".strip();
|
||||
final Cipher encrypt = CipherUtils.buildCipher(Cipher.ENCRYPT_MODE, Encrypt.DES, secret);
|
||||
final Cipher decrypt = CipherUtils.buildCipher(Cipher.DECRYPT_MODE, Encrypt.DES, secret);
|
||||
// 接收
|
||||
new Thread(() -> {
|
||||
int length = 0;
|
||||
short messageLength = 0;
|
||||
final byte[] bytes = new byte[1024];
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
|
||||
try {
|
||||
while((length = inputStream.read(bytes)) >= 0) {
|
||||
buffer.put(bytes, 0, length);
|
||||
while(buffer.position() > 0) {
|
||||
if(messageLength <= 0) {
|
||||
if(buffer.position() < Short.BYTES) {
|
||||
// 不够消息长度
|
||||
break;
|
||||
} else {
|
||||
buffer.flip();
|
||||
messageLength = buffer.getShort();
|
||||
buffer.compact();
|
||||
if(messageLength > 16 * 1024) {
|
||||
throw MessageCodeException.of("超过最大数据大小:" + messageLength);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(buffer.position() < messageLength) {
|
||||
// 不够消息长度
|
||||
break;
|
||||
} else {
|
||||
final byte[] message = new byte[messageLength];
|
||||
messageLength = 0;
|
||||
buffer.flip();
|
||||
buffer.get(message);
|
||||
buffer.compact();
|
||||
log.debug("收到消息:{}", new String(decrypt.doFinal(message)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("读取异常", e);
|
||||
}
|
||||
}).start();
|
||||
// 发送
|
||||
String line = """
|
||||
{
|
||||
"header":{"v":"1.0.0","id":1215293599999001,"signal":"client::register"},
|
||||
"body":{"clientId":"ffmpeg","name":"ffmpeg","clientType":"WEB","battery":100,"charging":true,"username":"taoyao","password":"taoyao"}
|
||||
}
|
||||
""";
|
||||
// {"header":{"v":"1.0.0","id":1215310510002009,"signal":"room::enter"},"body":{"roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9"}}
|
||||
// {"header":{"v":"1.0.0","id":1215310510002010,"signal":"media::transport::plain"},"body":{"roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9","rtcpMux":false,"comedia":true}}
|
||||
// {"header":{"v":"1.0.0","id":1215375110006012,"signal":"media::produce"},"body":{"kind":"video","roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9","transportId":"14dc9307-bf9c-4442-a9ad-ce6a97623ef4","appData":{},"rtpParameters":{"codecs":[{"mimeType":"video/vp8","clockRate":90000,"payloadType":102,"rtcpFeedback":[]}],"encodings":[{"ssrc":123123}]}}}
|
||||
// 音频转为PCM
|
||||
// ffmpeg.exe -i .\a.m4a -f s16le a.pcm
|
||||
// ffmpeg.exe -i .\a.m4a -f s16le -ac 2 -ar 8000 a.pcm
|
||||
// ffplay.exe -ar 48000 -ac 2 -f s16le -i a.pcm
|
||||
// ffmpeg不支持rtcpMux
|
||||
// ffmpeg -re -i video.mp4 -c:v vp8 -map 0:0 -f tee "[select=v:f=rtp:ssrc=123123:payload_type=102]rtp://192.168.1.110:40793?rtcpport=47218"
|
||||
// ffmpeg -re -i video.mp4 -c:v libvpx -map 0:0 -f tee "[select=v:f=rtp:ssrc=123123:payload_type=102]rtp://192.168.1.110:40793?rtcpport=47218"
|
||||
// 音频视频同时传输
|
||||
// ffmpeg -re -i video.mp4 -c:a libopus -vn -f rtp rtp://192.168.1.110:8888 -c:v libx264 -an -f rtp rtp://192.168.1.110:9999 -sdp_file taoyao.sdp
|
||||
// ffplay -protocol_whitelist "file,rtp,udp" -i taoyao.sdp
|
||||
// ffmpeg -protocol_whitelist "file,rtp,udp" -i taoyao.sdp taoyao.mp4
|
||||
final Scanner scanner = new Scanner(System.in);
|
||||
do {
|
||||
if(StringUtils.isEmpty(line)) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
final byte[] bytes = line.getBytes();
|
||||
final byte[] encryptBytes = encrypt.doFinal(bytes);
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(Short.BYTES + encryptBytes.length);
|
||||
buffer.putShort((short) encryptBytes.length);
|
||||
buffer.put(encryptBytes);
|
||||
buffer.flip();
|
||||
final byte[] message = new byte[buffer.capacity()];
|
||||
buffer.get(message);
|
||||
outputStream.write(message);
|
||||
} catch (Exception e) {
|
||||
log.error("发送异常", e);
|
||||
}
|
||||
} while((line = scanner.next()) != null);
|
||||
socket.close();
|
||||
scanner.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,29 +15,29 @@ import lombok.extern.slf4j.Slf4j;
|
||||
//@SpringBootTest(classes = TaoyaoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
|
||||
class IdServiceTest {
|
||||
|
||||
@Autowired
|
||||
private IdService idService;
|
||||
@Autowired
|
||||
private IdService idService;
|
||||
|
||||
@Test
|
||||
// @Timeout(value = 1000, unit = TimeUnit.MILLISECONDS)
|
||||
// @Rollback()
|
||||
// @RepeatedTest(10)
|
||||
void testId() {
|
||||
final long id = this.idService.buildId();
|
||||
log.info("生成ID:{}", id);
|
||||
log.info("生成ID:{}", String.valueOf(id).length());
|
||||
}
|
||||
@Test
|
||||
// @Timeout(value = 1000, unit = TimeUnit.MILLISECONDS)
|
||||
// @Rollback()
|
||||
// @RepeatedTest(10)
|
||||
void testId() {
|
||||
final long id = this.idService.buildId();
|
||||
log.info("生成ID:{}", id);
|
||||
log.info("生成ID:{}", String.valueOf(id).length());
|
||||
}
|
||||
|
||||
@Test
|
||||
@CostedTest(count = 100000, thread = 10)
|
||||
void testIdCosted() {
|
||||
this.idService.buildId();
|
||||
}
|
||||
@Test
|
||||
@CostedTest(count = 100000, thread = 10)
|
||||
void testIdCosted() {
|
||||
this.idService.buildId();
|
||||
}
|
||||
|
||||
@Test
|
||||
@CostedTest(count = 100000, thread = 10)
|
||||
void testUuidCosted() {
|
||||
this.idService.buildUuid();
|
||||
}
|
||||
@Test
|
||||
@CostedTest(count = 100000, thread = 10)
|
||||
void testUuidCosted() {
|
||||
this.idService.buildUuid();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user