[*] 日常优化

This commit is contained in:
acgist
2023-07-27 08:27:48 +08:00
parent 6e25afaddf
commit c9af50a324
6 changed files with 130 additions and 156 deletions

View File

@@ -94,13 +94,11 @@ const signalChannel = {
} }
me.heartbeatTimer = setTimeout(async () => { me.heartbeatTimer = setTimeout(async () => {
if (me.connected()) { if (me.connected()) {
me.push( me.taoyao.push(protocol.buildMessage("client::heartbeat", {
protocol.buildMessage("client::heartbeat", { // TODO电池信息
// TODO电池信息 battery : 100,
battery : 100, charging: true,
charging: true, }));
})
);
me.heartbeat(); me.heartbeat();
} else { } else {
console.warn("心跳失败", me.address); console.warn("心跳失败", me.address);
@@ -136,18 +134,18 @@ const signalChannel = {
me.channel = new WebSocket(me.address, { rejectUnauthorized: false, handshakeTimeout: 5000 }); me.channel = new WebSocket(me.address, { rejectUnauthorized: false, handshakeTimeout: 5000 });
me.channel.on("open", async () => { me.channel.on("open", async () => {
console.info("打开信令通道", me.address); console.info("打开信令通道", me.address);
me.push( const { body } = await me.taoyao.request(protocol.buildMessage("client::register", {
protocol.buildMessage("client::register", { name : config.signal.name,
name : config.signal.name, clientId : config.signal.clientId,
clientId : config.signal.clientId, clientType: config.signal.clientType,
clientType: config.signal.clientType, username : config.signal.username,
username : config.signal.username, password : config.signal.password,
password : config.signal.password, // TODO电池信息
// TODO电池信息 battery : 100,
battery : 100, charging : true,
charging : true, }));
}) protocol.clientIndex = body.index;
); console.info("终端注册成功", protocol.clientIndex);
me.reconnectionTimeout = me.minReconnectionDelay; me.reconnectionTimeout = me.minReconnectionDelay;
me.taoyao.connect = true; me.taoyao.connect = true;
me.heartbeat(); me.heartbeat();
@@ -206,19 +204,6 @@ const signalChannel = {
me.maxReconnectionDelay me.maxReconnectionDelay
); );
}, },
/**
* 异步请求
*
* @param {*} message 消息
*/
push(message) {
const me = this;
try {
me.channel.send(JSON.stringify(message));
} catch (error) {
console.error("异步请求异常", message, error);
}
},
/** /**
* 关闭通道 * 关闭通道
*/ */
@@ -409,9 +394,6 @@ class Taoyao {
case "client::reboot": case "client::reboot":
me.clientReboot(message, body); me.clientReboot(message, body);
break; break;
case "client::register":
me.clientRegister(message, body);
break;
case "client::shutdown": case "client::shutdown":
me.clientShutdown(message, body); me.clientShutdown(message, body);
break; break;
@@ -587,17 +569,6 @@ class Taoyao {
); );
} }
/**
* 终端注册信令
*
* @param {*} message 消息
* @param {*} body 消息主体
*/
clientRegister(message, body) {
protocol.clientIndex = body.index;
console.info("终端注册成功", protocol.clientIndex);
}
/** /**
* 关闭终端信令 * 关闭终端信令
* *

View File

@@ -101,7 +101,7 @@ const signalChannel = {
me.heartbeatTimer = setTimeout(async () => { me.heartbeatTimer = setTimeout(async () => {
if (me.connected()) { if (me.connected()) {
const battery = await navigator.getBattery(); const battery = await navigator.getBattery();
me.push(protocol.buildMessage("client::heartbeat", { me.taoyao.push(protocol.buildMessage("client::heartbeat", {
battery : battery.level * 100, battery : battery.level * 100,
charging: battery.charging, charging: battery.charging,
})); }));
@@ -141,7 +141,7 @@ const signalChannel = {
me.channel.onopen = async () => { me.channel.onopen = async () => {
console.info("打开信令通道", me.address); console.info("打开信令通道", me.address);
const battery = await navigator.getBattery(); const battery = await navigator.getBattery();
me.push(protocol.buildMessage("client::register", { const { body } = await me.taoyao.request(protocol.buildMessage("client::register", {
name : me.taoyao.name, name : me.taoyao.name,
clientId : me.taoyao.clientId, clientId : me.taoyao.clientId,
clientType: config.signal.clientType, clientType: config.signal.clientType,
@@ -150,6 +150,8 @@ const signalChannel = {
battery : battery.level * 100, battery : battery.level * 100,
charging : battery.charging, charging : battery.charging,
})); }));
protocol.clientIndex = body.index;
console.info("终端注册成功", protocol.clientIndex);
me.reconnectionTimeout = me.minReconnectionDelay; me.reconnectionTimeout = me.minReconnectionDelay;
me.taoyao.connect = true; me.taoyao.connect = true;
me.heartbeat(); me.heartbeat();
@@ -209,19 +211,6 @@ const signalChannel = {
me.maxReconnectionDelay me.maxReconnectionDelay
); );
}, },
/**
* 异步请求
*
* @param {*} message 消息
*/
push(message) {
const me = this;
try {
me.channel.send(JSON.stringify(message));
} catch (error) {
console.error("异步请求异常", message, error);
}
},
/** /**
* 关闭通道 * 关闭通道
*/ */
@@ -763,9 +752,6 @@ class Taoyao extends RemoteClient {
case "client::config": case "client::config":
me.defaultClientConfig(message); me.defaultClientConfig(message);
break; break;
case "client::register":
me.defaultClientRegister(message);
break;
case "media::consume": case "media::consume":
await me.defaultMediaConsume(message); await me.defaultMediaConsume(message);
break; break;
@@ -1046,11 +1032,22 @@ class Taoyao extends RemoteClient {
* @param {*} message 信令消息 * @param {*} message 信令消息
*/ */
defaultClientBroadcast(message) { defaultClientBroadcast(message) {
const me = this; const me = this;
const { header, body } = message; const {
header,
body,
} = message;
console.debug("终端广播", header, body); console.debug("终端广播", header, body);
} }
/**
* 关闭终端信令
*/
clientClose() {
const me = this;
me.push(protocol.buildMessage("client::close", {}));
}
/** /**
* 终端配置信令 * 终端配置信令
* *
@@ -1108,17 +1105,6 @@ class Taoyao extends RemoteClient {
location.reload(); location.reload();
} }
/**
* 终端注册信令
*
* @param {*} message 信令消息
*/
defaultClientRegister(message) {
const { body } = message;
protocol.clientIndex = body.index;
console.info("终端注册成功", protocol.clientIndex);
}
/** /**
* 关闭终端信令 * 关闭终端信令
* *
@@ -2150,7 +2136,9 @@ class Taoyao extends RemoteClient {
*/ */
async mediaProduce(audioTrack, videoTrack) { async mediaProduce(audioTrack, videoTrack) {
const me = this; const me = this;
me.checkDevice(); if(!audioTrack || !videoTrack) {
me.checkDevice();
}
await me.createSendTransport(); await me.createSendTransport();
await me.createRecvTransport(); await me.createRecvTransport();
await me.produceAudio(audioTrack); await me.produceAudio(audioTrack);

View File

@@ -40,6 +40,10 @@ public abstract class ClientAdapter<T extends AutoCloseable> implements Client {
* 终端实例 * 终端实例
*/ */
protected final T instance; protected final T instance;
/**
* 是否关闭
*/
protected boolean close;
/** /**
* 是否授权 * 是否授权
*/ */
@@ -62,6 +66,7 @@ public abstract class ClientAdapter<T extends AutoCloseable> implements Client {
this.time = System.currentTimeMillis(); this.time = System.currentTimeMillis();
this.timeout = timeout; this.timeout = timeout;
this.instance = instance; this.instance = instance;
this.close = false;
this.authorized = false; this.authorized = false;
this.status = new ClientStatus(); this.status = new ClientStatus();
this.requestMessage = new ConcurrentHashMap<>(); this.requestMessage = new ConcurrentHashMap<>();
@@ -152,6 +157,10 @@ public abstract class ClientAdapter<T extends AutoCloseable> implements Client {
@Override @Override
public void close() throws Exception { public void close() throws Exception {
if(this.close) {
return;
}
this.close = true;
log.info("关闭终端实例:{} - {}", this.ip, this.clientId); log.info("关闭终端实例:{} - {}", this.ip, this.clientId);
this.instance.close(); this.instance.close();
} }

View File

@@ -24,43 +24,47 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@Protocol @Protocol
@Description( @Description(
memo = "同时释放所有资源,所以如果终端意外掉线重连,需要终端实现音视频重连逻辑。", memo = """
信令连接断开以后执行,同时释放所有资源。
如果终端意外掉线,需要自己实现重连逻辑。
""",
flow = { flow = {
"终端->信令服务->终端", "终端->信令服务->终端",
"终端->信令服务-[终端下线])终端" "终端-[关闭终端]>信令服务-[终端下线])终端",
"终端-[连接断开]>信令服务-[终端下线])终端"
} }
) )
public class ClientCloseProtocol extends ProtocolClientAdapter implements ApplicationListener<ClientCloseEvent> { public class ClientCloseProtocol extends ProtocolClientAdapter implements ApplicationListener<ClientCloseEvent> {
public static final String SIGNAL = "client::close"; public static final String SIGNAL = "client::close";
public ClientCloseProtocol() { public ClientCloseProtocol() {
super("关闭终端信令", SIGNAL); super("关闭终端信令", SIGNAL);
} }
@Async @Async
@Override @Override
public void onApplicationEvent(ClientCloseEvent event) { public void onApplicationEvent(ClientCloseEvent event) {
this.close(event.getClient()); this.close(event.getClient());
} }
@Override @Override
public void execute(String clientId, ClientType clientType, Client client, Message message, Map<String, Object> body) { public void execute(String clientId, ClientType clientType, Client client, Message message, Map<String, Object> body) {
client.push(message.cloneWithoutBody()); client.push(message.cloneWithoutBody());
try { try {
// 关闭连接后会发布事件 // 关闭连接后会发布事件
client.close(); client.close();
} catch (Exception e) { } catch (Exception e) {
log.error("关闭终端异常:{}", clientId, e); log.error("关闭终端异常:{}", clientId, e);
} }
} }
/** /**
* 关闭终端 * 关闭终端
* *
* @param client 终端 * @param client 终端
*/ */
private void close(Client client) { private void close(Client client) {
if(client == null || client.unauthorized()) { if(client == null || client.unauthorized()) {
// 没有授权终端 // 没有授权终端
return; return;
@@ -73,6 +77,6 @@ public class ClientCloseProtocol extends ProtocolClientAdapter implements Applic
this.sessionManager.close(client); this.sessionManager.close(client);
// 终端下线事件 // 终端下线事件
this.publishEvent(new ClientOfflineEvent(client)); this.publishEvent(new ClientOfflineEvent(client));
} }
} }

View File

@@ -27,60 +27,61 @@ import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter;
*/ */
@Protocol @Protocol
@Description( @Description(
memo = "终端应该在收到配置之后进行媒体操作",
body = """ body = """
{ {
"media": "媒体配置(可选)", "media" : "媒体配置(可选)",
"webrtc": "WebRTC配置可选", "webrtc" : "WebRTC配置可选",
"datetime": "日期时间yyyyMMddHHmmss" "datetime": "日期时间yyyyMMddHHmmss"
} }
""", """,
flow = "终端=[终端注册]>信令服务->终端" flow = "终端=[终端注册]>信令服务-[终端配置]>终端"
) )
public class ClientConfigProtocol extends ProtocolClientAdapter implements ApplicationListener<ClientConfigEvent> { public class ClientConfigProtocol extends ProtocolClientAdapter implements ApplicationListener<ClientConfigEvent> {
public static final String SIGNAL = "client::config"; public static final String SIGNAL = "client::config";
private final MediaProperties mediaProperties; private final MediaProperties mediaProperties;
private final WebrtcProperties webrtcProperties; private final WebrtcProperties webrtcProperties;
public ClientConfigProtocol(MediaProperties mediaProperties, WebrtcProperties webrtcProperties) { public ClientConfigProtocol(MediaProperties mediaProperties, WebrtcProperties webrtcProperties) {
super("终端配置信令", SIGNAL); super("终端配置信令", SIGNAL);
this.mediaProperties = mediaProperties; this.mediaProperties = mediaProperties;
this.webrtcProperties = webrtcProperties; this.webrtcProperties = webrtcProperties;
}
@Async
@Override
public void onApplicationEvent(ClientConfigEvent event) {
final Client client = event.getClient();
final ClientType clientType = client.getClientType();
client.push(this.build(clientType));
} }
@Override @Async
public void execute(String clientId, ClientType clientType, Client client, Message message, Map<String, Object> body) { @Override
client.push(this.build(clientType)); public void onApplicationEvent(ClientConfigEvent event) {
} final Client client = event.getClient();
final ClientType clientType = client.getClientType();
/** client.push(this.build(clientType));
* @param clientType 终端类型 }
*
* @return 消息 @Override
*/ public void execute(String clientId, ClientType clientType, Client client, Message message, Map<String, Object> body) {
public Message build(ClientType clientType) { client.push(this.build(clientType));
final Message message = super.build(); }
final Map<String, Object> config = new HashMap<>();
// 日期时间 /**
config.put(Constant.DATETIME, DateUtils.format(LocalDateTime.now(), DateTimeStyle.YYYYMMDDHH24MMSS)); * @param clientType 终端类型
// Web、摄像头媒体配置 *
if(clientType.mediaClient()) { * @return 消息
config.put(Constant.MEDIA, this.mediaProperties); */
config.put(Constant.WEBRTC, this.webrtcProperties); public Message build(ClientType clientType) {
} else { final Message message = super.build();
this.logNoAdapter(clientType); final Map<String, Object> config = new HashMap<>();
} // 日期时间
message.setBody(config); config.put(Constant.DATETIME, DateUtils.format(LocalDateTime.now(), DateTimeStyle.YYYYMMDDHH24MMSS));
return message; // 媒体终端:媒体配置
} if(clientType.mediaClient()) {
config.put(Constant.MEDIA, this.mediaProperties);
config.put(Constant.WEBRTC, this.webrtcProperties);
} else {
this.logNoAdapter(clientType);
}
message.setBody(config);
return message;
}
} }

View File

@@ -29,6 +29,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@Protocol @Protocol
@Description( @Description(
memo = "收到注册响应之后应该设置终端的终端索引",
body = """ body = """
{ {
"username": "信令用户", "username": "信令用户",