From c9af50a324fe3cf478d63bfb404ac8ffe442ccdc Mon Sep 17 00:00:00 2001 From: acgist <289547414@qq.com> Date: Thu, 27 Jul 2023 08:27:48 +0800 Subject: [PATCH] =?UTF-8?q?[*]=20=E6=97=A5=E5=B8=B8=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taoyao-client-media/src/Taoyao.js | 63 ++++-------- taoyao-client-web/src/components/Taoyao.js | 52 ++++------ .../taoyao/signal/client/ClientAdapter.java | 9 ++ .../protocol/client/ClientCloseProtocol.java | 66 +++++++------ .../protocol/client/ClientConfigProtocol.java | 95 ++++++++++--------- .../client/ClientRegisterProtocol.java | 1 + 6 files changed, 130 insertions(+), 156 deletions(-) diff --git a/taoyao-client-media/src/Taoyao.js b/taoyao-client-media/src/Taoyao.js index dec6b16..1bc9a9c 100644 --- a/taoyao-client-media/src/Taoyao.js +++ b/taoyao-client-media/src/Taoyao.js @@ -94,13 +94,11 @@ const signalChannel = { } me.heartbeatTimer = setTimeout(async () => { if (me.connected()) { - me.push( - protocol.buildMessage("client::heartbeat", { - // TODO:电池信息 - battery : 100, - charging: true, - }) - ); + me.taoyao.push(protocol.buildMessage("client::heartbeat", { + // TODO:电池信息 + battery : 100, + charging: true, + })); me.heartbeat(); } else { console.warn("心跳失败", me.address); @@ -136,18 +134,18 @@ const signalChannel = { me.channel = new WebSocket(me.address, { rejectUnauthorized: false, handshakeTimeout: 5000 }); me.channel.on("open", async () => { console.info("打开信令通道", me.address); - me.push( - protocol.buildMessage("client::register", { - name : config.signal.name, - clientId : config.signal.clientId, - clientType: config.signal.clientType, - username : config.signal.username, - password : config.signal.password, - // TODO:电池信息 - battery : 100, - charging : true, - }) - ); + const { body } = await me.taoyao.request(protocol.buildMessage("client::register", { + name : config.signal.name, + clientId : config.signal.clientId, + clientType: config.signal.clientType, + username : config.signal.username, + password : config.signal.password, + // TODO:电池信息 + battery : 100, + charging : true, + })); + protocol.clientIndex = body.index; + console.info("终端注册成功", protocol.clientIndex); me.reconnectionTimeout = me.minReconnectionDelay; me.taoyao.connect = true; me.heartbeat(); @@ -206,19 +204,6 @@ const signalChannel = { 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": me.clientReboot(message, body); break; - case "client::register": - me.clientRegister(message, body); - break; case "client::shutdown": me.clientShutdown(message, body); break; @@ -587,17 +569,6 @@ class Taoyao { ); } - /** - * 终端注册信令 - * - * @param {*} message 消息 - * @param {*} body 消息主体 - */ - clientRegister(message, body) { - protocol.clientIndex = body.index; - console.info("终端注册成功", protocol.clientIndex); - } - /** * 关闭终端信令 * diff --git a/taoyao-client-web/src/components/Taoyao.js b/taoyao-client-web/src/components/Taoyao.js index 8d672db..8d05b8e 100644 --- a/taoyao-client-web/src/components/Taoyao.js +++ b/taoyao-client-web/src/components/Taoyao.js @@ -101,7 +101,7 @@ const signalChannel = { me.heartbeatTimer = setTimeout(async () => { if (me.connected()) { const battery = await navigator.getBattery(); - me.push(protocol.buildMessage("client::heartbeat", { + me.taoyao.push(protocol.buildMessage("client::heartbeat", { battery : battery.level * 100, charging: battery.charging, })); @@ -141,7 +141,7 @@ const signalChannel = { me.channel.onopen = async () => { console.info("打开信令通道", me.address); 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, clientId : me.taoyao.clientId, clientType: config.signal.clientType, @@ -150,6 +150,8 @@ const signalChannel = { battery : battery.level * 100, charging : battery.charging, })); + protocol.clientIndex = body.index; + console.info("终端注册成功", protocol.clientIndex); me.reconnectionTimeout = me.minReconnectionDelay; me.taoyao.connect = true; me.heartbeat(); @@ -209,19 +211,6 @@ const signalChannel = { 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": me.defaultClientConfig(message); break; - case "client::register": - me.defaultClientRegister(message); - break; case "media::consume": await me.defaultMediaConsume(message); break; @@ -1046,11 +1032,22 @@ class Taoyao extends RemoteClient { * @param {*} message 信令消息 */ defaultClientBroadcast(message) { - const me = this; - const { header, body } = message; + const me = this; + const { + header, + body, + } = message; console.debug("终端广播", header, body); } + /** + * 关闭终端信令 + */ + clientClose() { + const me = this; + me.push(protocol.buildMessage("client::close", {})); + } + /** * 终端配置信令 * @@ -1108,17 +1105,6 @@ class Taoyao extends RemoteClient { 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) { const me = this; - me.checkDevice(); + if(!audioTrack || !videoTrack) { + me.checkDevice(); + } await me.createSendTransport(); await me.createRecvTransport(); await me.produceAudio(audioTrack); diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientAdapter.java index 26ca761..c9905a7 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientAdapter.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientAdapter.java @@ -40,6 +40,10 @@ public abstract class ClientAdapter implements Client { * 终端实例 */ protected final T instance; + /** + * 是否关闭 + */ + protected boolean close; /** * 是否授权 */ @@ -62,6 +66,7 @@ public abstract class ClientAdapter implements Client { this.time = System.currentTimeMillis(); this.timeout = timeout; this.instance = instance; + this.close = false; this.authorized = false; this.status = new ClientStatus(); this.requestMessage = new ConcurrentHashMap<>(); @@ -152,6 +157,10 @@ public abstract class ClientAdapter implements Client { @Override public void close() throws Exception { + if(this.close) { + return; + } + this.close = true; log.info("关闭终端实例:{} - {}", this.ip, this.clientId); this.instance.close(); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientCloseProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientCloseProtocol.java index fb871a9..9a5538f 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientCloseProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientCloseProtocol.java @@ -24,43 +24,47 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @Protocol @Description( - memo = "同时释放所有资源,所以如果终端意外掉线重连,需要终端实现音视频重连逻辑。", + memo = """ + 信令连接断开以后执行,同时释放所有资源。 + 如果终端意外掉线,需要自己实现重连逻辑。 + """, flow = { "终端->信令服务->终端", - "终端->信令服务-[终端下线])终端" + "终端-[关闭终端]>信令服务-[终端下线])终端", + "终端-[连接断开]>信令服务-[终端下线])终端" } ) public class ClientCloseProtocol extends ProtocolClientAdapter implements ApplicationListener { - public static final String SIGNAL = "client::close"; - - public ClientCloseProtocol() { - super("关闭终端信令", SIGNAL); - } - - @Async - @Override - public void onApplicationEvent(ClientCloseEvent event) { - this.close(event.getClient()); - } + public static final String SIGNAL = "client::close"; + + public ClientCloseProtocol() { + super("关闭终端信令", SIGNAL); + } + + @Async + @Override + public void onApplicationEvent(ClientCloseEvent event) { + this.close(event.getClient()); + } - @Override - public void execute(String clientId, ClientType clientType, Client client, Message message, Map body) { - client.push(message.cloneWithoutBody()); - try { - // 关闭连接后会发布事件 - client.close(); - } catch (Exception e) { - log.error("关闭终端异常:{}", clientId, e); - } - } - - /** - * 关闭终端 - * - * @param client 终端 - */ - private void close(Client client) { + @Override + public void execute(String clientId, ClientType clientType, Client client, Message message, Map body) { + client.push(message.cloneWithoutBody()); + try { + // 关闭连接后会发布事件 + client.close(); + } catch (Exception e) { + log.error("关闭终端异常:{}", clientId, e); + } + } + + /** + * 关闭终端 + * + * @param client 终端 + */ + private void close(Client client) { if(client == null || client.unauthorized()) { // 没有授权终端 return; @@ -73,6 +77,6 @@ public class ClientCloseProtocol extends ProtocolClientAdapter implements Applic this.sessionManager.close(client); // 终端下线事件 this.publishEvent(new ClientOfflineEvent(client)); - } + } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientConfigProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientConfigProtocol.java index 485c67b..17a9c96 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientConfigProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientConfigProtocol.java @@ -27,60 +27,61 @@ import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; */ @Protocol @Description( + memo = "终端应该在收到配置之后进行媒体操作", body = """ { - "media": "媒体配置(可选)", - "webrtc": "WebRTC配置(可选)", + "media" : "媒体配置(可选)", + "webrtc" : "WebRTC配置(可选)", "datetime": "日期时间(yyyyMMddHHmmss)" } """, - flow = "终端=[终端注册]>信令服务->终端" + flow = "终端=[终端注册]>信令服务-[终端配置]>终端" ) public class ClientConfigProtocol extends ProtocolClientAdapter implements ApplicationListener { - public static final String SIGNAL = "client::config"; - - private final MediaProperties mediaProperties; - private final WebrtcProperties webrtcProperties; - - public ClientConfigProtocol(MediaProperties mediaProperties, WebrtcProperties webrtcProperties) { - super("终端配置信令", SIGNAL); - this.mediaProperties = mediaProperties; - 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)); + public static final String SIGNAL = "client::config"; + + private final MediaProperties mediaProperties; + private final WebrtcProperties webrtcProperties; + + public ClientConfigProtocol(MediaProperties mediaProperties, WebrtcProperties webrtcProperties) { + super("终端配置信令", SIGNAL); + this.mediaProperties = mediaProperties; + this.webrtcProperties = webrtcProperties; } - - @Override - public void execute(String clientId, ClientType clientType, Client client, Message message, Map body) { - client.push(this.build(clientType)); - } - - /** - * @param clientType 终端类型 - * - * @return 消息 - */ - public Message build(ClientType clientType) { - final Message message = super.build(); - final Map config = new HashMap<>(); - // 日期时间 - config.put(Constant.DATETIME, DateUtils.format(LocalDateTime.now(), DateTimeStyle.YYYYMMDDHH24MMSS)); - // Web、摄像头:媒体配置 - if(clientType.mediaClient()) { - config.put(Constant.MEDIA, this.mediaProperties); - config.put(Constant.WEBRTC, this.webrtcProperties); - } else { - this.logNoAdapter(clientType); - } - message.setBody(config); - return message; - } - + + @Async + @Override + public void onApplicationEvent(ClientConfigEvent event) { + final Client client = event.getClient(); + final ClientType clientType = client.getClientType(); + client.push(this.build(clientType)); + } + + @Override + public void execute(String clientId, ClientType clientType, Client client, Message message, Map body) { + client.push(this.build(clientType)); + } + + /** + * @param clientType 终端类型 + * + * @return 消息 + */ + public Message build(ClientType clientType) { + final Message message = super.build(); + final Map config = new HashMap<>(); + // 日期时间 + config.put(Constant.DATETIME, DateUtils.format(LocalDateTime.now(), DateTimeStyle.YYYYMMDDHH24MMSS)); + // 媒体终端:媒体配置 + if(clientType.mediaClient()) { + config.put(Constant.MEDIA, this.mediaProperties); + config.put(Constant.WEBRTC, this.webrtcProperties); + } else { + this.logNoAdapter(clientType); + } + message.setBody(config); + return message; + } + } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientRegisterProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientRegisterProtocol.java index aee58e7..bebfbcd 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientRegisterProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientRegisterProtocol.java @@ -29,6 +29,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @Protocol @Description( + memo = "收到注册响应之后应该设置终端的终端索引", body = """ { "username": "信令用户",