This commit is contained in:
acgist
2023-02-11 22:11:51 +08:00
parent 50f80bee2d
commit 5f85dfccca
112 changed files with 1770 additions and 1213 deletions

View File

@@ -14,8 +14,8 @@ import org.springframework.stereotype.Component;
* @author acgist
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Client {

View File

@@ -9,13 +9,13 @@ import java.lang.annotation.Target;
import org.springframework.stereotype.Component;
/**
* 监听
* 事件监听
*
* @author acgist
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {

View File

@@ -14,8 +14,8 @@ import org.springframework.stereotype.Component;
* @author acgist
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Manager {

View File

@@ -14,8 +14,8 @@ import org.springframework.stereotype.Component;
* @author acgist
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Protocol {

View File

@@ -90,11 +90,9 @@ public class BootAutoConfiguration {
@Value("${spring.application.name:taoyao}")
private String name;
@Value("${taoyao.webrtc.framework:MOON}")
private String framework;
@Autowired
private ApplicationContext context;
private ApplicationContext applicationContext;
@Bean
@ConditionalOnMissingBean
@@ -169,13 +167,12 @@ public class BootAutoConfiguration {
log.info("用户目录:{}", System.getProperty("user.home"));
log.info("临时目录:{}", System.getProperty("java.io.tmpdir"));
log.info("文件编码:{}", System.getProperty("file.encoding"));
this.context.getBeansOfType(TaskExecutor.class).forEach((k, v) -> {
this.applicationContext.getBeansOfType(TaskExecutor.class).forEach((k, v) -> {
log.info("系统任务线程池:{}-{}", k, v);
});
this.context.getBeansOfType(TaskScheduler.class).forEach((k, v) -> {
this.applicationContext.getBeansOfType(TaskScheduler.class).forEach((k, v) -> {
log.info("系统定时任务线程池:{}-{}", k, v);
});
log.info("WebRTC架构{}", this.framework);
this.registerException();
}
@@ -203,7 +200,6 @@ public class BootAutoConfiguration {
@PreDestroy
public void destroy() {
log.info("系统关闭:{}", this.name);
// TODO通知关闭
// 刷出日志缓存
final ILoggerFactory factory = LoggerFactory.getILoggerFactory();
if (factory instanceof LoggerContext context) {

View File

@@ -11,7 +11,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import com.acgist.taoyao.boot.property.SecurityProperties;
import com.acgist.taoyao.boot.property.TaoyaoProperties;
import io.swagger.v3.oas.models.Components;
@@ -31,9 +30,15 @@ import io.swagger.v3.oas.models.security.SecurityScheme;
@Configuration
@ConditionalOnClass(OpenAPI.class)
public class SpringDocAutoConfiguration {
/**
* Basic认证
*/
private static final String BASIC = "Basic";
@Value("${server.port:8888}")
private Integer port;
@Autowired
private TaoyaoProperties taoyaoProperties;
@@ -101,7 +106,7 @@ public class SpringDocAutoConfiguration {
private List<SecurityRequirement> buildSecurity() {
return List.of(
new SecurityRequirement()
.addList(SecurityProperties.BASIC)
.addList(BASIC)
);
}
@@ -110,7 +115,7 @@ public class SpringDocAutoConfiguration {
*/
private Components buildComponents() {
return new Components()
.addSecuritySchemes(SecurityProperties.BASIC, this.buildSecurityScheme());
.addSecuritySchemes(BASIC, this.buildSecurityScheme());
}
/**
@@ -118,8 +123,8 @@ public class SpringDocAutoConfiguration {
*/
private SecurityScheme buildSecurityScheme() {
return new SecurityScheme()
.name(SecurityProperties.BASIC)
.scheme(SecurityProperties.BASIC)
.name(BASIC)
.scheme(BASIC)
.in(SecurityScheme.In.HEADER)
.type(SecurityScheme.Type.HTTP);
}

View File

@@ -20,15 +20,15 @@ import lombok.extern.slf4j.Slf4j;
public class WebMvcConfigurerAutoConfiguration implements WebMvcConfigurer {
@Autowired
private ApplicationContext context;
private ApplicationContext applicationContext;
@Override
public void addInterceptors(InterceptorRegistry registry) {
this.context.getBeansOfType(InterceptorAdapter.class).entrySet().stream()
this.applicationContext.getBeansOfType(InterceptorAdapter.class).entrySet().stream()
.sorted((a, z) -> a.getValue().compareTo(z.getValue()))
.forEach(entry -> {
final InterceptorAdapter value = entry.getValue();
log.info("加载拦截器:{}-{}", entry.getKey(), value.name());
log.info("加载拦截器:{} - {}", String.format("%-32s", entry.getKey()), value.name());
registry.addInterceptor(value).addPathPatterns(value.pathPattern());
});
}

View File

@@ -10,29 +10,29 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* 请求响应头部
* 消息头部
*
* @author acgist
*/
@Getter
@Setter
@Schema( title = "请求响应头部", description = "请求响应头部")
@Schema( title = "消息头部", description = "消息头部")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Header implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 请求响应版本
* 消息版本
*/
@Schema(title = "请求响应版本", description = "请求响应版本")
@Schema(title = "消息版本", description = "消息版本")
private String v;
/**
* 请求响应标识
* 消息标识
*/
@Schema(title = "请求响应标识", description = "请求响应标识")
@Schema(title = "消息标识", description = "消息标识")
private String id;
/**
* 终端标识
@@ -45,4 +45,9 @@ public class Header implements Serializable {
@Schema(title = "协议标识", description = "协议标识")
private String signal;
@Override
public Header clone() {
return new Header(this.v, this.id, this.sn, this.signal);
}
}

View File

@@ -14,13 +14,13 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* 请求响应消息
* 消息
*
* @author acgist
*/
@Getter
@Setter
@Schema(title = "请求响应消息", description = "请求响应消息")
@Schema(title = "消息", description = "消息")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@@ -29,28 +29,28 @@ public class Message implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
/**
* 响应编码
* 状态编码
*/
@Schema(title = "响应编码", description = "响应消息标识响应状态")
@Schema(title = "状态编码", description = "状态编码")
private String code;
/**
* 响应描述
* 状态描述
*/
@Schema(title = "响应描述", description = "响应消息描述响应编码")
@Schema(title = "状态描述", description = "状态描述")
private String message;
/**
* 请求响应头部
* 消息头部
*/
@Schema(title = "请求响应头部", description = "请求响应头部")
@Schema(title = "消息头部", description = "消息头部")
private Header header;
/**
* 请求响应主体
* 消息主体
*/
@Schema(title = "请求响应主体", description = "请求响应主体")
@Schema(title = "消息主体", description = "消息主体")
private Object body;
/**
* 覆盖
* 重载方法
*
* @param code 状态编码
*/
@@ -60,27 +60,20 @@ public class Message implements Cloneable, Serializable {
/**
* @param code 状态编码
*
* @return this
*/
public Message setCode(MessageCode code) {
this.code = code.getCode();
this.message = code.getMessage();
return this;
public void setCode(MessageCode code) {
this.setCode(code, null);
}
/**
* @param code 响应编码
* @param message 响应描述
* @param code 状态编码
* @param message 状态描述
*
* @return this
*/
public Message setCode(MessageCode code, String message) {
if(StringUtils.isEmpty(message)) {
message = code.getMessage();
}
this.code = code.getCode();
this.message = message;
this.message = StringUtils.isEmpty(message) ? code.getMessage() : message;
return this;
}
@@ -92,14 +85,13 @@ public class Message implements Cloneable, Serializable {
}
/**
* @param body 主体
* @param body 消息主体
*
* @return 成功消息
*/
public static final Message success(Object body) {
final Message message = new Message();
message.code = MessageCode.CODE_0000.getCode();
message.message = MessageCode.CODE_0000.getMessage();
message.setCode(MessageCode.CODE_0000, null);
message.body = body;
return message;
}
@@ -112,16 +104,7 @@ public class Message implements Cloneable, Serializable {
}
/**
* @param message 主体
*
* @return 错误消息
*/
public static final Message fail(String message) {
return fail(null, message, null);
}
/**
* @param code 响应编码
* @param code 状态编码
*
* @return 错误消息
*/
@@ -130,8 +113,37 @@ public class Message implements Cloneable, Serializable {
}
/**
* @param code 响应编码
* @param message 响应描述
* @param code 状态编码
* @param body 消息主体
*
* @return 错误消息
*/
public static final Message fail(MessageCode code, Object body) {
return fail(code, null, body);
}
/**
* @param message 状态描述
*
* @return 错误消息
*/
public static final Message fail(String message) {
return fail(null, message, null);
}
/**
* @param message 状态描述
* @param body 消息主体
*
* @return 错误消息
*/
public static final Message fail(String message, Object body) {
return fail(null, message, body);
}
/**
* @param code 状态编码
* @param message 状态描述
*
* @return 错误消息
*/
@@ -140,58 +152,33 @@ public class Message implements Cloneable, Serializable {
}
/**
* @param code 响应编码
* @param body 主体
*
* @return 错误消息
*/
public static final Message fail(MessageCode code, Object body) {
return fail(code, null, body);
}
/**
* @param code 响应编码
* @param message 响应描述
* @param body 主体
* @param code 状态编码
* @param message 状态描述
* @param body 消息主体
*
* @return 错误消息
*/
public static final Message fail(MessageCode code, String message, Object body) {
if(code == null) {
code = MessageCode.CODE_9999;
}
if (StringUtils.isEmpty(message)) {
message = code.getMessage();
}
final Message failMessage = new Message();
failMessage.code = code.getCode();
failMessage.message = message;
failMessage.setCode(code == null ? MessageCode.CODE_9999 : code, message);
failMessage.body = body;
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 new Message(this.code, this.message, this.header.clone(), this.body);
}
/**
* 克隆排除主体
* 克隆排除消息主体
*
* @return 请求响应消息
* @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);
}
final Message message = this.clone();
message.setBody(null);
return message;
}
@Override

View File

@@ -5,10 +5,10 @@ import lombok.Getter;
/**
* 状态编码
*
* 1xxx=前置错误:数据校验
* 2xxx=内部错误
* 3xxx=请求错误HTTP错误
* 9999=未知错误
* 1xxx = 前置错误
* 2xxx = 内部错误
* 3xxx = 请求错误
* 9999 = 未知错误
*
* @author acgist
*/
@@ -43,8 +43,8 @@ public enum MessageCode {
/**
* HTTP状态编码前缀
*/
public static final String HTTP_STATUS = "3";
private static final String HTTP_STATUS = "3";
/**
* 状态编码
*/
@@ -80,7 +80,7 @@ public enum MessageCode {
}
/**
* @param status HTTPStatus
* @param status HTTP Status
*
* @return 状态编码
*/

View File

@@ -7,59 +7,59 @@ import lombok.Getter;
import lombok.Setter;
/**
* 媒体终端配置
* 媒体服务配置
*
* @author acgist
*/
@Getter
@Setter
@Schema(title = "Mediasoup配置", description = "Mediasoup配置")
@Schema(title = "媒体服务配置", description = "媒体服务配置")
public class MediasoupProperties {
/**
* Mediasoup名称
* 名称
*/
@Schema(title = "Mediasoup名称", description = "Mediasoup名称")
@Schema(title = "名称", description = "名称")
private String name;
/**
* Mediasoup主机
* 是否启用
*/
@Schema(title = "Mediasoup主机", description = "Mediasoup主机")
@Schema(title = "是否启用", description = "是否启用")
private Boolean enabled;
/**
* 主机
*/
@Schema(title = "主机", description = "主机")
private String host;
/**
* Mediasoup端口
* 端口
*/
@Schema(title = "Mediasoup端口", description = "Mediasoup端口")
@Schema(title = "端口", description = "端口")
private Integer port;
/**
* Mediasoup协议
* 协议
*/
@Schema(title = "Mediasoup协议", description = "Mediasoup协议")
@Schema(title = "协议", description = "协议")
private String schema;
/**
* Mediasoup地址
* 用户
*/
@Schema(title = "Mediasoup地址", description = "Mediasoup地址")
private String websocket;
/**
* Mediasoup用户
*/
@Schema(title = "Mediasoup用户", description = "Mediasoup用户")
@Schema(title = "用户", description = "用户")
@JsonIgnore
private String username;
/**
* Mediasoup密码
* 密码
*/
@Schema(title = "Mediasoup密码", description = "Mediasoup密码")
@Schema(title = "密码", description = "密码")
@JsonIgnore
private String password;
/**
* @return 完整Mediasoup地址
* @return 完整地址
*/
@Schema(title = "完整Mediasoup地址", description = "完整Mediasoup地址")
@Schema(title = "完整地址", description = "完整地址")
public String getAddress() {
return this.schema + "://" + this.host + ":" + this.port + this.websocket;
return this.schema + "://" + this.host + ":" + this.port;
}
}

View File

@@ -17,25 +17,25 @@ import lombok.Setter;
public class NodeProperties {
/**
* 节点主机
* 主机
*/
@Schema(title = "节点主机", description = "节点主机")
@Schema(title = "主机", description = "主机")
private String host;
/**
* 节点端口
* 端口
*/
@Schema(title = "节点端口", description = "节点端口")
@Schema(title = "端口", description = "端口")
private Integer port;
/**
* 用户
*/
@Schema(title = "节点用户", description = "节点用户")
@Schema(title = "用户", description = "用户")
@JsonIgnore
private String username;
/**
* 密码
*/
@Schema(title = "节点密码", description = "节点密码")
@Schema(title = "密码", description = "密码")
@JsonIgnore
private String password;
/**

View File

@@ -15,11 +15,6 @@ import lombok.Setter;
@ConfigurationProperties(prefix = "taoyao.security")
public class SecurityProperties {
/**
* Basic认证
*/
public static final String BASIC = "Basic";
/**
* 是否启用
*/

View File

@@ -30,19 +30,19 @@ public class WebrtcProperties {
@Schema(title = "媒体最大端口", description = "媒体最大端口")
private Integer maxPort;
/**
* stun服务器
* STUN服务器
*/
@Schema(title = "stun服务器", description = "stun服务器")
@Schema(title = "STUN服务器", description = "STUN服务器")
private String[] stun;
/**
* turn服务器
* TURN服务器
*/
@Schema(title = "turn服务器", description = "turn服务器")
@Schema(title = "TURN服务器", description = "TURN服务器")
private String[] turn;
/**
* Mediasoup配置
* 媒体服务配置
*/
@Schema(title = "Mediasoup配置", description = "Mediasoup配置")
@Schema(title = "媒体服务配置", description = "媒体服务配置")
private List<MediasoupProperties> mediasoupList;
}

View File

@@ -0,0 +1,65 @@
package com.acgist.taoyao.boot.utils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import jakarta.websocket.Session;
import lombok.extern.slf4j.Slf4j;
/**
* WebSocket工具
*
* @author acgist
*/
@Slf4j
public class WebSocketUtils {
private WebSocketUtils() {
}
/**
* @param session WebSocket
*
* @return 远程地址
*/
public static final String getRemoteAddress(Session session) {
if (session == null) {
return null;
}
return (String) getField(session.getAsyncRemote(), "base.socketWrapper.remoteAddr");
}
/**
* @param object 对象
* @param fieldPath 属性路径
*
* @return 属性
*/
private static final Object getField(Object object, String fieldPath) {
final String fields[] = StringUtils.split(fieldPath, '.');
for (String field : fields) {
object = getField(object, object.getClass(), field);
if (object == null) {
return null;
}
}
return object;
}
/**
* @param object 对象
* @param clazz 属性类型
* @param fieldName 属性名称
*
* @return 属性
*/
private static final Object getField(Object object, Class<?> clazz, String fieldName) {
try {
return FieldUtils.getField(clazz, fieldName, true).get(object);
} catch (IllegalArgumentException | IllegalAccessException e) {
log.error("读取属性异常:{}-{}", clazz, fieldName, e);
}
return null;
}
}