[*] 日常优化
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.acgist.taoyao.boot.utils;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.nio.channels.AsynchronousChannelGroup;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -45,4 +46,19 @@ public final class CloseableUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭通道线程池
|
||||
*
|
||||
* @param group 通道线程池
|
||||
*/
|
||||
public static final void shutdown(AsynchronousChannelGroup group) {
|
||||
try {
|
||||
if(group != null) {
|
||||
group.shutdown();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("关闭通道线程池异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ public abstract class ClientAdapter<T extends AutoCloseable> implements Client {
|
||||
* @param instance 终端实例
|
||||
*/
|
||||
protected ClientAdapter(long timeout, T instance) {
|
||||
this.ip = this.getClientIP(instance);
|
||||
this.time = System.currentTimeMillis();
|
||||
this.timeout = timeout;
|
||||
this.instance = instance;
|
||||
@@ -151,9 +152,19 @@ public abstract class ClientAdapter<T extends AutoCloseable> implements Client {
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
log.info("关闭终端实例:{} - {}", this.ip, this.clientId);
|
||||
this.instance.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析终端IP
|
||||
*
|
||||
* @param instance 终端实例
|
||||
*
|
||||
* @return 终端IP
|
||||
*/
|
||||
protected abstract String getClientIP(T instance);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + " - " + this.ip + " - " + this.clientId;
|
||||
|
||||
@@ -69,7 +69,7 @@ public class ClientManager {
|
||||
*/
|
||||
public void unicast(Client to, Message message) {
|
||||
this.clients().stream()
|
||||
.filter(v -> v.getInstance() == to)
|
||||
.filter(v -> v == to)
|
||||
.forEach(v -> v.push(message));
|
||||
}
|
||||
|
||||
@@ -105,14 +105,14 @@ public class ClientManager {
|
||||
*/
|
||||
public void broadcast(Client from, Message message, ClientType ... clientTypes) {
|
||||
this.clients(clientTypes).stream()
|
||||
.filter(v -> v.getInstance() != from)
|
||||
.filter(v -> v != from)
|
||||
.forEach(v -> v.push(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param instance 终端实例
|
||||
*
|
||||
* @return 终端
|
||||
* @return 终端(包含授权和未授权)
|
||||
*/
|
||||
public Client clients(AutoCloseable instance) {
|
||||
return this.clients.stream()
|
||||
@@ -122,7 +122,7 @@ public class ClientManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId 终端标识
|
||||
* @param clientId 终端ID
|
||||
*
|
||||
* @return 授权终端
|
||||
*/
|
||||
@@ -136,7 +136,7 @@ public class ClientManager {
|
||||
/**
|
||||
* @param clientTypes 终端类型
|
||||
*
|
||||
* @return 所有授权终端列表
|
||||
* @return 授权终端列表
|
||||
*/
|
||||
public List<Client> clients(ClientType ... clientTypes) {
|
||||
return this.clients.stream()
|
||||
@@ -156,7 +156,7 @@ public class ClientManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId 终端标识
|
||||
* @param clientId 终端ID
|
||||
*
|
||||
* @return 授权终端状态
|
||||
*/
|
||||
@@ -168,7 +168,7 @@ public class ClientManager {
|
||||
/**
|
||||
* @param clientTypes 终端类型
|
||||
*
|
||||
* @return 所有授权终端状态列表
|
||||
* @return 授权终端状态列表
|
||||
*/
|
||||
public List<ClientStatus> status(ClientType ... clientTypes) {
|
||||
return this.clients(clientTypes).stream()
|
||||
@@ -208,9 +208,7 @@ public class ClientManager {
|
||||
log.error("关闭终端异常:{}", instance, e);
|
||||
} finally {
|
||||
if(client != null) {
|
||||
// 移除管理
|
||||
this.clients.remove(client);
|
||||
// 关闭事件
|
||||
this.applicationContext.publishEvent(new ClientCloseEvent(client));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,12 +49,12 @@ public class ClientStatus {
|
||||
private Boolean clientRecording;
|
||||
@Schema(title = "服务端是否正在录像", description = "服务端是否正在录像")
|
||||
private Boolean serverRecording;
|
||||
@Schema(title = "最后心跳时间", description = "最后心跳时间")
|
||||
private LocalDateTime lastHeartbeat;
|
||||
@Schema(title = "终端状态", description = "其他扩展终端状态")
|
||||
private Map<String, Object> status = new HashMap<>();
|
||||
@Schema(title = "终端配置", description = "其他扩展终端配置")
|
||||
private Map<String, Object> config = new HashMap<>();
|
||||
@Schema(title = "最后心跳时间", description = "最后心跳时间")
|
||||
private LocalDateTime lastHeartbeat;
|
||||
|
||||
/**
|
||||
* 拷贝属性
|
||||
|
||||
@@ -14,10 +14,25 @@ import lombok.Getter;
|
||||
@Getter
|
||||
public enum ClientType {
|
||||
|
||||
/**
|
||||
* 通过浏览器接入的终端
|
||||
*/
|
||||
WEB("Web"),
|
||||
/**
|
||||
* 媒体服务终端
|
||||
*/
|
||||
MEDIA("媒体服务"),
|
||||
/**
|
||||
* 没有界面的摄像头
|
||||
*/
|
||||
CAMERA("摄像头"),
|
||||
/**
|
||||
* 手机APP、平板APP
|
||||
*/
|
||||
MOBILE("移动端"),
|
||||
/**
|
||||
* 其他智能终端
|
||||
*/
|
||||
OTHER("其他终端");
|
||||
|
||||
/**
|
||||
@@ -33,7 +48,10 @@ public enum ClientType {
|
||||
* @return 是否是媒体终端
|
||||
*/
|
||||
public boolean mediaClient() {
|
||||
return this == WEB || this == CAMERA || this == MOBILE;
|
||||
return
|
||||
this == WEB ||
|
||||
this == CAMERA ||
|
||||
this == MOBILE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +67,8 @@ public enum ClientType {
|
||||
* @return 类型
|
||||
*/
|
||||
public static final ClientType of(String value) {
|
||||
for (ClientType type : ClientType.values()) {
|
||||
final ClientType[] types = ClientType.values();
|
||||
for (ClientType type : types) {
|
||||
if(type.name().equalsIgnoreCase(value)) {
|
||||
return type;
|
||||
}
|
||||
@@ -58,12 +77,17 @@ public enum ClientType {
|
||||
}
|
||||
|
||||
/**
|
||||
* 媒体终端
|
||||
* 媒体终端类型列表
|
||||
*/
|
||||
public static final ClientType[] MEDIA_CLIENT = Stream.of(ClientType.values()).filter(ClientType::mediaClient).toArray(ClientType[]::new);
|
||||
public static final ClientType[] MEDIA_CLIENT_TYPE
|
||||
=
|
||||
Stream.of(ClientType.values()).filter(ClientType::mediaClient).toArray(ClientType[]::new);
|
||||
|
||||
/**
|
||||
* 媒体服务
|
||||
* 媒体服务类型列表
|
||||
*/
|
||||
public static final ClientType[] MEDIA_SERVER = Stream.of(ClientType.values()).filter(ClientType::mediaServer).toArray(ClientType[]::new);
|
||||
public static final ClientType[] MEDIA_SERVER_TYPE
|
||||
=
|
||||
Stream.of(ClientType.values()).filter(ClientType::mediaServer).toArray(ClientType[]::new);
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ public class SocketClient extends ClientAdapter<AsynchronousSocketChannel> {
|
||||
|
||||
public SocketClient(SocketProperties socketProperties, AsynchronousSocketChannel instance) {
|
||||
super(socketProperties.getTimeout(), instance);
|
||||
this.ip = this.clientIp(instance);
|
||||
this.cipher = CipherUtils.buildCipher(Cipher.ENCRYPT_MODE, socketProperties.getEncrypt(), socketProperties.getEncryptSecret());
|
||||
}
|
||||
|
||||
@@ -65,16 +64,12 @@ public class SocketClient extends ClientAdapter<AsynchronousSocketChannel> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param instance 终端实例
|
||||
*
|
||||
* @return 终端IP
|
||||
*/
|
||||
private String clientIp(AsynchronousSocketChannel instance) {
|
||||
@Override
|
||||
protected String getClientIP(AsynchronousSocketChannel instance) {
|
||||
try {
|
||||
return ((InetSocketAddress) instance.getRemoteAddress()).getHostString();
|
||||
} catch (IOException e) {
|
||||
throw MessageCodeException.of(e, "无效终端(IP):" + instance);
|
||||
throw MessageCodeException.of(e, "无效终端IP:" + instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,17 +22,15 @@ import lombok.extern.slf4j.Slf4j;
|
||||
/**
|
||||
* Socket信令
|
||||
*
|
||||
* TODO:加密
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
@Slf4j
|
||||
public class SocketSignal {
|
||||
|
||||
private ClientManager clientManager;
|
||||
private ProtocolManager protocolManager;
|
||||
private SocketProperties socketProperties;
|
||||
private PlatformErrorProtocol platformErrorProtocol;
|
||||
private final ClientManager clientManager;
|
||||
private final ProtocolManager protocolManager;
|
||||
private final SocketProperties socketProperties;
|
||||
private final PlatformErrorProtocol platformErrorProtocol;
|
||||
|
||||
/**
|
||||
* 线程序号
|
||||
@@ -45,7 +43,7 @@ public class SocketSignal {
|
||||
/**
|
||||
* 服务端通道
|
||||
*/
|
||||
private AsynchronousServerSocketChannel channel;
|
||||
private AsynchronousServerSocketChannel server;
|
||||
|
||||
public SocketSignal(
|
||||
ClientManager clientManager,
|
||||
@@ -76,9 +74,9 @@ public class SocketSignal {
|
||||
this.newThreadFactory()
|
||||
);
|
||||
this.group = AsynchronousChannelGroup.withThreadPool(executor);
|
||||
this.channel = AsynchronousServerSocketChannel.open(this.group);
|
||||
this.channel.bind(new InetSocketAddress(host, port));
|
||||
this.channel.accept(this.channel, new SocketSignalAcceptHandler(
|
||||
this.server = AsynchronousServerSocketChannel.open(this.group);
|
||||
this.server.bind(new InetSocketAddress(host, port));
|
||||
this.server.accept(this.server, new SocketSignalAcceptHandler(
|
||||
this.clientManager,
|
||||
this.protocolManager,
|
||||
this.socketProperties,
|
||||
@@ -117,11 +115,9 @@ public class SocketSignal {
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
log.debug("关闭Socket信令服务:{}", this.channel);
|
||||
CloseableUtils.close(this.channel);
|
||||
if(this.group != null) {
|
||||
this.group.shutdown();
|
||||
}
|
||||
log.debug("关闭Socket信令服务:{}", this.server);
|
||||
CloseableUtils.close(this.server);
|
||||
CloseableUtils.shutdown(this.group);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public final class SocketSignalAcceptHandler implements CompletionHandler<AsynchronousSocketChannel, AsynchronousServerSocketChannel> {
|
||||
|
||||
private ClientManager clientManager;
|
||||
private ProtocolManager protocolManager;
|
||||
private SocketProperties socketProperties;
|
||||
private PlatformErrorProtocol platformErrorProtocol;
|
||||
private final ClientManager clientManager;
|
||||
private final ProtocolManager protocolManager;
|
||||
private final SocketProperties socketProperties;
|
||||
private final PlatformErrorProtocol platformErrorProtocol;
|
||||
|
||||
public SocketSignalAcceptHandler(
|
||||
ClientManager clientManager,
|
||||
@@ -47,8 +47,8 @@ public final class SocketSignalAcceptHandler implements CompletionHandler<Asynch
|
||||
this.clientManager,
|
||||
this.protocolManager,
|
||||
this.socketProperties,
|
||||
channel,
|
||||
this.platformErrorProtocol
|
||||
this.platformErrorProtocol,
|
||||
channel
|
||||
);
|
||||
messageHandler.loopMessage();
|
||||
log.debug("Socket信令终端连接成功:{}", channel);
|
||||
|
||||
@@ -10,7 +10,6 @@ import javax.crypto.IllegalBlockSizeException;
|
||||
|
||||
import com.acgist.taoyao.boot.config.SocketProperties;
|
||||
import com.acgist.taoyao.boot.model.MessageCodeException;
|
||||
import com.acgist.taoyao.boot.utils.CloseableUtils;
|
||||
import com.acgist.taoyao.signal.client.ClientManager;
|
||||
import com.acgist.taoyao.signal.protocol.ProtocolManager;
|
||||
import com.acgist.taoyao.signal.protocol.platform.PlatformErrorProtocol;
|
||||
@@ -27,9 +26,9 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public final class SocketSignalMessageHandler implements CompletionHandler<Integer, ByteBuffer> {
|
||||
|
||||
private ClientManager clientManager;
|
||||
private ProtocolManager protocolManager;
|
||||
private PlatformErrorProtocol platformErrorProtocol;
|
||||
private final ClientManager clientManager;
|
||||
private final ProtocolManager protocolManager;
|
||||
private final PlatformErrorProtocol platformErrorProtocol;
|
||||
|
||||
/**
|
||||
* 消息长度
|
||||
@@ -60,18 +59,18 @@ public final class SocketSignalMessageHandler implements CompletionHandler<Integ
|
||||
ClientManager clientManager,
|
||||
ProtocolManager protocolManager,
|
||||
SocketProperties socketProperties,
|
||||
AsynchronousSocketChannel channel,
|
||||
PlatformErrorProtocol platformErrorProtocol
|
||||
PlatformErrorProtocol platformErrorProtocol,
|
||||
AsynchronousSocketChannel channel
|
||||
) {
|
||||
this.clientManager = clientManager;
|
||||
this.protocolManager = protocolManager;
|
||||
this.platformErrorProtocol = platformErrorProtocol;
|
||||
this.channel = channel;
|
||||
this.messageLength = 0;
|
||||
this.bufferSize = socketProperties.getBufferSize();
|
||||
this.maxBufferSize = socketProperties.getMaxBufferSize();
|
||||
this.cipher = CipherUtils.buildCipher(Cipher.DECRYPT_MODE, socketProperties.getEncrypt(), socketProperties.getEncryptSecret());
|
||||
this.buffer = ByteBuffer.allocateDirect(maxBufferSize);
|
||||
this.channel = channel;
|
||||
this.clientManager = clientManager;
|
||||
this.protocolManager = protocolManager;
|
||||
this.platformErrorProtocol = platformErrorProtocol;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +91,6 @@ public final class SocketSignalMessageHandler implements CompletionHandler<Integ
|
||||
*/
|
||||
private void close() {
|
||||
log.debug("Socket信令终端关闭:{}", this.channel);
|
||||
CloseableUtils.close(this.channel);
|
||||
this.clientManager.close(this.channel);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ public class WebSocketClient extends ClientAdapter<Session> {
|
||||
|
||||
public WebSocketClient(long timeout, Session instance) {
|
||||
super(timeout, instance);
|
||||
this.ip = (String) instance.getUserProperties().get(Constant.IP);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,4 +38,9 @@ public class WebSocketClient extends ClientAdapter<Session> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getClientIP(Session instance) {
|
||||
return (String) instance.getUserProperties().get(Constant.IP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public class RoomCreateProtocol extends ProtocolClientAdapter implements Applica
|
||||
);
|
||||
message.setBody(room.getRoomStatus());
|
||||
// 通知媒体终端
|
||||
this.clientManager.broadcast(message, ClientType.MEDIA_CLIENT);
|
||||
this.clientManager.broadcast(message, ClientType.MEDIA_CLIENT_TYPE);
|
||||
} else {
|
||||
this.logNoAdapter(clientType);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user