[*] 日常优化

This commit is contained in:
acgist
2023-06-13 08:10:37 +08:00
parent c35869df0c
commit ebda8b0bbd
11 changed files with 159 additions and 114 deletions

View File

@@ -8,35 +8,35 @@ package com.acgist.taoyao.media.config;
public class Config { public class Config {
/** /**
* 屏幕捕获 * 屏幕捕获消息
*/ */
public static final int WHAT_SCREEN_CAPTURE = 1000; public static final int WHAT_SCREEN_CAPTURE = 1000;
/** /**
* 视频录像 * 视频录像消息
*/ */
public static final int WHAT_RECORD = 1001; public static final int WHAT_RECORD = 1001;
/** /**
* 新建本地音频 * 新建本地音频消息
*/ */
public static final int WHAT_NEW_LOCAL_AUDIO = 2000; public static final int WHAT_NEW_LOCAL_AUDIO = 2000;
/** /**
* 新建本地视频 * 新建本地视频消息
*/ */
public static final int WHAT_NEW_LOCAL_VIDEO = 2001; public static final int WHAT_NEW_LOCAL_VIDEO = 2001;
/** /**
* 新建远程音频 * 新建远程音频消息
*/ */
public static final int WHAT_NEW_REMOTE_AUDIO = 2002; public static final int WHAT_NEW_REMOTE_AUDIO = 2002;
/** /**
* 新建远程视频 * 新建远程视频消息
*/ */
public static final int WHAT_NEW_REMOTE_VIDEO = 2003; public static final int WHAT_NEW_REMOTE_VIDEO = 2003;
/** /**
* 移除远程音频 * 移除远程音频消息
*/ */
public static final int WHAT_REMOVE_AUDIO = 2998; public static final int WHAT_REMOVE_AUDIO = 2998;
/** /**
* 移除远程视频 * 移除远程视频消息
*/ */
public static final int WHAT_REMOVE_VIDEO = 2999; public static final int WHAT_REMOVE_VIDEO = 2999;
/** /**

View File

@@ -2,71 +2,76 @@ package com.acgist.taoyao.media.config;
/** /**
* 音频配置 * 音频配置
* *
* 注意:完全拷贝信令模块`MediaAudioProperties`代码
*
* @author acgist * @author acgist
*/ */
public class MediaAudioProperties { public class MediaAudioProperties {
/** /**
* 音频格式 * 音频格式
* *
* @author acgist * @author acgist
*/ */
public enum Format { public enum Format {
G722,
PCMA,
PCMU,
OPUS;
}
/** G722,
* 格式G722|PCMA|PCMU|OPUS // G711A
*/ PCMA,
private Format format; // G711U
/** PCMU,
* 比特率96|128|256 OPUS;
*/
private Integer bitrate;
/**
* 采样位数8|16|32
*/
private Integer sampleSize;
/**
* 采样率8000|16000|32000|48000
*/
private Integer sampleRate;
public Format getFormat() { }
return this.format;
}
public void setFormat(Format format) { /**
this.format = format; * 格式G722|PCMA|PCMU|OPUS
} */
private Format format;
/**
* 比特率96|128|256
*/
private Integer bitrate;
/**
* 采样位数位深8|16|32
*/
private Integer sampleSize;
/**
* 采样率8000|16000|32000|48000
*/
private Integer sampleRate;
public Integer getBitrate() { public Format getFormat() {
return bitrate; return this.format;
} }
public void setBitrate(Integer bitrate) { public void setFormat(Format format) {
this.bitrate = bitrate; this.format = format;
} }
public Integer getSampleSize() { public Integer getBitrate() {
return this.sampleSize; return bitrate;
} }
public void setSampleSize(Integer sampleSize) { public void setBitrate(Integer bitrate) {
this.sampleSize = sampleSize; this.bitrate = bitrate;
} }
public Integer getSampleRate() { public Integer getSampleSize() {
return this.sampleRate; return this.sampleSize;
} }
public void setSampleSize(Integer sampleSize) {
this.sampleSize = sampleSize;
}
public Integer getSampleRate() {
return this.sampleRate;
}
public void setSampleRate(Integer sampleRate) {
this.sampleRate = sampleRate;
}
public void setSampleRate(Integer sampleRate) {
this.sampleRate = sampleRate;
}
} }

View File

@@ -5,6 +5,8 @@ import java.util.Map;
/** /**
* 媒体配置 * 媒体配置
* *
* 注意:完全拷贝信令模块`MediaProperties`代码
*
* @author acgist * @author acgist
*/ */
public class MediaProperties { public class MediaProperties {

View File

@@ -2,23 +2,25 @@ package com.acgist.taoyao.media.config;
/** /**
* 视频配置 * 视频配置
* *
* 注意:完全拷贝信令模块`MediaVideoProperties`代码
*
* @author acgist * @author acgist
*/ */
public class MediaVideoProperties { public class MediaVideoProperties {
/** /**
* 视频格式 * 视频格式
* *
* @author acgist * @author acgist
*/ */
public enum Format { public enum Format {
VP8, VP8,
VP9, VP9,
H264, H264,
H265; H265;
} }
/** /**
@@ -96,4 +98,5 @@ public class MediaVideoProperties {
public void setHeight(Integer height) { public void setHeight(Integer height) {
this.height = height; this.height = height;
} }
} }

View File

@@ -22,21 +22,21 @@ public class MediaAudioProperties {
* @author acgist * @author acgist
*/ */
public enum Format { public enum Format {
G722, G722,
// G711A // G711A
PCMA, PCMA,
// G711U // G711U
PCMU, PCMU,
OPUS; OPUS;
} }
@Schema(title = "格式", description = "格式", example = "G722|PCMA|PCMU|OPUS") @Schema(title = "格式", description = "格式", example = "G722|PCMA|PCMU|OPUS")
private Format format; private Format format;
@Schema(title = "比特率", description = "比特率", example = "96|128|256") @Schema(title = "比特率", description = "比特率", example = "96|128|256")
private Integer bitrate; private Integer bitrate;
@Schema(title = "采样位数", description = "采样位数", example = "8|16|32") @Schema(title = "采样位数(位深)", description = "采样位数(位深)", example = "8|16|32")
private Integer sampleSize; private Integer sampleSize;
@Schema(title = "采样率", description = "采样率", example = "8000|16000|32000|48000") @Schema(title = "采样率", description = "采样率", example = "8000|16000|32000|48000")
private Integer sampleRate; private Integer sampleRate;

View File

@@ -17,16 +17,16 @@ import lombok.Setter;
@Schema(title = "安全配置", description = "安全配置") @Schema(title = "安全配置", description = "安全配置")
@ConfigurationProperties(prefix = "taoyao.security") @ConfigurationProperties(prefix = "taoyao.security")
public class SecurityProperties { public class SecurityProperties {
@Schema(title = "是否启用", description = "是否启用") @Schema(title = "是否启用", description = "是否启用")
private Boolean enabled; private Boolean enabled;
@Schema(title = "安全范围", description = "安全范围") @Schema(title = "安全范围", description = "安全范围")
private String realm; private String realm;
@Schema(title = "公共地址", description = "公共地址") @Schema(title = "公共地址", description = "公共地址")
private String[] permit; private String[] permit;
@Schema(title = "名称", description = "名称") @Schema(title = "帐号", description = "帐号")
private String username; private String username;
@Schema(title = "密码", description = "密码") @Schema(title = "密码", description = "密码")
private String password; private String password;
} }

View File

@@ -1,8 +1,8 @@
package com.acgist.taoyao.boot.utils; package com.acgist.taoyao.boot.utils;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -15,6 +15,7 @@ import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.boot.model.MessageCode; import com.acgist.taoyao.boot.model.MessageCode;
import com.acgist.taoyao.boot.model.MessageCodeException; import com.acgist.taoyao.boot.model.MessageCodeException;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolation;
@@ -78,7 +79,7 @@ public final class ErrorUtils {
* @return 错误消息 * @return 错误消息
*/ */
public static final Message message(HttpServletRequest request, HttpServletResponse response) { public static final Message message(HttpServletRequest request, HttpServletResponse response) {
return message(null, request, response); return ErrorUtils.message(null, request, response);
} }
/** /**
@@ -91,11 +92,11 @@ public final class ErrorUtils {
public static final Message message(Throwable t, HttpServletRequest request, HttpServletResponse response) { public static final Message message(Throwable t, HttpServletRequest request, HttpServletResponse response) {
final Message message; final Message message;
// 错误状态编码 // 错误状态编码
int status = globalStatus(request, response); int status = ErrorUtils.globalStatus(request, response);
// 全局异常 // 全局异常
final Object globalError = t == null ? globalError(request) : t; final Object globalError = t == null ? ErrorUtils.globalError(request) : t;
// 原始异常 // 原始异常
final Object rootError = rootException(globalError); final Object rootError = ErrorUtils.rootException(globalError);
if(rootError instanceof MessageCodeException messageCodeException) { if(rootError instanceof MessageCodeException messageCodeException) {
// 状态编码异常 // 状态编码异常
final MessageCode messageCode = messageCodeException.getMessageCode(); final MessageCode messageCode = messageCodeException.getMessageCode();
@@ -103,9 +104,9 @@ public final class ErrorUtils {
message = Message.fail(messageCode, messageCodeException.getMessage()); message = Message.fail(messageCode, messageCodeException.getMessage());
} else if(rootError instanceof Throwable throwable) { } else if(rootError instanceof Throwable throwable) {
// 未知异常:异常转换 // 未知异常:异常转换
final MessageCode messageCode = messageCode(status, throwable); final MessageCode messageCode = ErrorUtils.messageCode(status, throwable);
status = messageCode.getStatus(); status = messageCode.getStatus();
message = Message.fail(messageCode, message(messageCode, throwable)); message = Message.fail(messageCode, ErrorUtils.message(messageCode, throwable));
} else { } else {
// 没有异常 // 没有异常
final MessageCode messageCode = MessageCode.of(status); final MessageCode messageCode = MessageCode.of(status);
@@ -116,9 +117,19 @@ public final class ErrorUtils {
status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
} }
response.setStatus(status); response.setStatus(status);
// 打印信息 // 请求地址
final String path = Objects.toString(request.getAttribute(SERVLET_REQUEST_URI), request.getServletPath()); final String path = ErrorUtils.getFirstParams(
final String query = request.getQueryString(); request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI),
request.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH),
request.getAttribute(SERVLET_REQUEST_URI),
request.getServletPath()
);
// 请求参数
final String query = ErrorUtils.getFirstParams(
request.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING),
request.getQueryString()
);
// 请求方法
final String method = request.getMethod(); final String method = request.getMethod();
if(globalError instanceof Throwable) { if(globalError instanceof Throwable) {
log.error(""" log.error("""
@@ -140,11 +151,11 @@ public final class ErrorUtils {
原始信息:{} 原始信息:{}
""", path, query, method, message, status, globalError); """, path, query, method, message, status, globalError);
} }
// final Map<String, String> body = new HashMap<>(); final Map<String, String> body = new HashMap<>();
// body.put("url", path); body.put("path", path);
// body.put("query", query); body.put("query", query);
// body.put("method", method); body.put("method", method);
// message.setBody(body); message.setBody(body);
return message; return message;
} }
@@ -241,7 +252,7 @@ public final class ErrorUtils {
*/ */
public static final Object rootException(Object t) { public static final Object rootException(Object t) {
if(t instanceof Throwable throwable) { if(t instanceof Throwable throwable) {
return rootException(throwable); return ErrorUtils.rootException(throwable);
} }
return t; return t;
} }
@@ -263,4 +274,18 @@ public final class ErrorUtils {
return t; return t;
} }
/**
* @param params 参数列表
*
* @return 首个参数
*/
private static final String getFirstParams(Object ... params) {
for (Object object : params) {
if(object != null) {
return object.toString();
}
}
return null;
}
} }

View File

@@ -40,7 +40,10 @@ public class TaoyaoAutoConfiguration {
@Bean @Bean
@ConditionalOnProperty(prefix = "taoyao.security", name = "enabled", havingValue = "true", matchIfMissing = true) @ConditionalOnProperty(prefix = "taoyao.security", name = "enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnMissingBean @ConditionalOnMissingBean
public SecurityInterceptor securityInterceptor(SecurityService securityService, SecurityProperties securityProperties) { public SecurityInterceptor securityInterceptor(
SecurityService securityService,
SecurityProperties securityProperties
) {
return new SecurityInterceptor(securityService, securityProperties); return new SecurityInterceptor(securityService, securityProperties);
} }

View File

@@ -27,16 +27,22 @@ public class SecurityInterceptor extends InterceptorAdapter {
private final SecurityService securityService; private final SecurityService securityService;
private final SecurityProperties securityProperties; private final SecurityProperties securityProperties;
public SecurityInterceptor(SecurityService securityService, SecurityProperties securityProperties) { /**
this.securityService = securityService; * 鉴权信息
this.securityProperties = securityProperties; */
log.info("安全拦截密码:{}", securityProperties.getPassword()); private final String authenticate;
} /**
/**
* 地址匹配 * 地址匹配
*/ */
private final AntPathMatcher matcher = new AntPathMatcher(); private final AntPathMatcher matcher;
public SecurityInterceptor(SecurityService securityService, SecurityProperties securityProperties) {
this.securityService = securityService;
this.securityProperties = securityProperties;
this.authenticate = "Basic Realm=\"" + this.securityProperties.getRealm() + "\"";
this.matcher = new AntPathMatcher();
log.info("安全拦截密码:{}", securityProperties.getPassword());
}
@Override @Override
public String name() { public String name() {
@@ -62,7 +68,7 @@ public class SecurityInterceptor extends InterceptorAdapter {
log.debug("授权失败:{}", request.getRequestURL()); log.debug("授权失败:{}", request.getRequestURL());
} }
response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic Realm=\"" + this.securityProperties.getRealm() + "\""); response.setHeader(HttpHeaders.WWW_AUTHENTICATE, this.authenticate);
return false; return false;
} }
@@ -72,7 +78,7 @@ public class SecurityInterceptor extends InterceptorAdapter {
* @return 是否许可请求 * @return 是否许可请求
*/ */
private boolean permit(HttpServletRequest request) { private boolean permit(HttpServletRequest request) {
final String uri = request.getRequestURI(); final String uri = request.getRequestURI();
final String[] permit = this.securityProperties.getPermit(); final String[] permit = this.securityProperties.getPermit();
if(ArrayUtils.isEmpty(permit)) { if(ArrayUtils.isEmpty(permit)) {
return false; return false;

View File

@@ -17,14 +17,15 @@ public class SlowInterceptor extends InterceptorAdapter {
private final TaoyaoProperties taoyaoProperties; private final TaoyaoProperties taoyaoProperties;
public SlowInterceptor(TaoyaoProperties taoyaoProperties) { /**
this.taoyaoProperties = taoyaoProperties;
}
/**
* 请求开始时间 * 请求开始时间
*/ */
private final ThreadLocal<Long> local = new ThreadLocal<>(); private final ThreadLocal<Long> local;
public SlowInterceptor(TaoyaoProperties taoyaoProperties) {
this.taoyaoProperties = taoyaoProperties;
this.local = new ThreadLocal<>();
}
@Override @Override
public String name() { public String name() {
@@ -52,7 +53,7 @@ public class SlowInterceptor extends InterceptorAdapter {
final long duration; final long duration;
final Long last = this.local.get(); final Long last = this.local.get();
if(last != null && (duration = System.currentTimeMillis() - last) > this.taoyaoProperties.getTimeout()) { if(last != null && (duration = System.currentTimeMillis() - last) > this.taoyaoProperties.getTimeout()) {
log.info("请求执行时间过慢:{}-{}", request.getRequestURI(), duration); log.info("请求执行时间过慢:{} - {}", request.getRequestURI(), duration);
} }
this.local.remove(); this.local.remove();
} }

View File

@@ -1,7 +1,7 @@
package com.acgist.taoyao.signal.service; package com.acgist.taoyao.signal.service;
/** /**
* 用户密码认证服务 * 帐号密码认证服务
* *
* @author acgist * @author acgist
*/ */
@@ -10,8 +10,8 @@ public interface UsernamePasswordService {
/** /**
* 认证 * 认证
* *
* @param username 用户名称 * @param username 帐号
* @param password 用户密码 * @param password 密码
* *
* @return 是否成功 * @return 是否成功
*/ */