From 2784eb6b9b9c5b7116be8c0f3c747135cb056b09 Mon Sep 17 00:00:00 2001 From: acgist <289547414@qq.com> Date: Sun, 30 Jul 2023 08:29:43 +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-web/src/App.vue | 2 +- taoyao-client-web/src/components/Taoyao.js | 107 +++++++++------ .../signal/event/client/ClientCloseEvent.java | 2 +- .../event/room/MediaServerRegisterEvent.java | 27 ++++ .../signal/event/room/RoomCreateEvent.java | 19 --- .../protocol/client/ClientCloseProtocol.java | 4 +- .../client/ClientOfflineProtocol.java | 17 ++- .../protocol/client/ClientOnlineProtocol.java | 46 +++---- .../protocol/client/ClientRebootProtocol.java | 24 ++-- .../client/ClientRegisterProtocol.java | 126 +++++++++--------- .../protocol/room/RoomCreateProtocol.java | 7 +- 11 files changed, 211 insertions(+), 170 deletions(-) create mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/MediaServerRegisterEvent.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomCreateEvent.java diff --git a/taoyao-client-web/src/App.vue b/taoyao-client-web/src/App.vue index b2959f4..74368ff 100644 --- a/taoyao-client-web/src/App.vue +++ b/taoyao-client-web/src/App.vue @@ -165,7 +165,7 @@ export default { async loadList() { this.rooms = await this.taoyao.roomList(); this.medias = await this.taoyao.mediaList(); - this.clients = await this.taoyao.clientList(); + this.clients = await this.taoyao.mediaClientList(); }, async sessionCall() { this.taoyao.sessionCall(this.room.callClientId); diff --git a/taoyao-client-web/src/components/Taoyao.js b/taoyao-client-web/src/components/Taoyao.js index a517970..e477706 100644 --- a/taoyao-client-web/src/components/Taoyao.js +++ b/taoyao-client-web/src/components/Taoyao.js @@ -777,6 +777,12 @@ class Taoyao extends RemoteClient { case "client::broadcast": me.defaultClientBroadcast(message); break; + case "client::offline": + me.defaultClientOffline(message); + break; + case "client::online": + me.defaultClientOnline(message); + break; case "client::reboot": me.defaultClientReboot(message); break; @@ -998,7 +1004,7 @@ class Taoyao extends RemoteClient { */ clientAlarm(message) { const me = this; - const date = new Date(); + const date = new Date(); const datetime = "" + date.getFullYear() + ((date.getMonth() < 9 ? "0" : "") + (date.getMonth() + 1)) + @@ -1043,41 +1049,10 @@ class Taoyao extends RemoteClient { /** * 关闭终端信令 */ - clientClose() { + async clientClose() { const me = this; - me.push(protocol.buildMessage("client::close", {})); - } - - /** - * @returns 媒体服务列表 - */ - async mediaList() { - const response = await this.request(protocol.buildMessage("client::list", { - clientType: "MEDIA" - })); - return response.body; - } - - /** - * @returns 媒体终端列表 - */ - async mediaClientList() { - const response = await this.request(protocol.buildMessage("client::list", {})); - return response.body.filter(v => { - return v.clientType === "WEB" || v.clientType === "CAMERA" || v.clientType === "MOBILE"; - }); - } - - /** - * @param {*} clientType 终端类型(默认所有) - * - * @returns 终端列表 - */ - async clientList(clientType) { - const response = await this.request(protocol.buildMessage("client::list", { - clientType - })); - return response.body; + await me.request(protocol.buildMessage("client::close", {})); + me.closeAll(); } /** @@ -1114,7 +1089,10 @@ class Taoyao extends RemoteClient { ideal: video.frameRate, max : media.maxFrameRate, }; - me.options = Object.keys(media.videos).map(key => ({value: key, label: media.videos[key].resolution})); + me.options = Object.keys(media.videos).map(key => ({ + value: key, + label: media.videos[key].resolution + })); me.mediaConfig = media; me.webrtcConfig = webrtc; console.debug( @@ -1127,13 +1105,63 @@ class Taoyao extends RemoteClient { ); } + /** + * @returns 媒体服务列表 + */ + async mediaList() { + const response = await this.request(protocol.buildMessage("client::list", { + clientType: "MEDIA" + })); + return response.body; + } + + /** + * @returns 媒体终端列表 + */ + async mediaClientList() { + const response = await this.request(protocol.buildMessage("client::list", {})); + return response.body.filter(v => { + return v.clientType === "WEB" || v.clientType === "CAMERA" || v.clientType === "MOBILE"; + }); + } + + /** + * @param {*} clientType 终端类型(可选) + * + * @returns 终端列表 + */ + async clientList(clientType) { + const response = await this.request(protocol.buildMessage("client::list", { + clientType + })); + return response.body; + } + + /** + * 终端下线信令 + * + * @param {*} message 信令消息 + */ + defaultClientOffline(message) { + console.debug("终端下线", message); + } + + /** + * 终端上线信令 + * + * @param {*} message 信令消息 + */ + defaultClientOnline(message) { + console.debug("终端上线", message); + } + /** * 重启终端信令 * * @param {*} message 信令消息 */ defaultClientReboot(message) { - console.info("重启终端"); + console.info("重启终端", message); location.reload(); } @@ -1143,7 +1171,7 @@ class Taoyao extends RemoteClient { * @param {*} message 消息 */ defaultClientShutdown(message) { - console.info("关闭终端"); + console.info("关闭终端", message); window.close(); } @@ -1837,10 +1865,11 @@ class Taoyao extends RemoteClient { * @param {*} message 消息 */ defaultPlatformError(message) { + const me = this; const { code } = message; if (code === "3401") { // 没有授权直接关闭 - signalChannel.close(); + me.closeAll(); } else { console.warn("平台异常", message); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/ClientCloseEvent.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/ClientCloseEvent.java index 23c9a81..ed4419f 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/ClientCloseEvent.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/ClientCloseEvent.java @@ -4,7 +4,7 @@ import com.acgist.taoyao.signal.client.Client; import com.acgist.taoyao.signal.event.ClientEventAdapter; /** - * 终端关闭事件 + * 关闭终端事件 * * @author acgist */ diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/MediaServerRegisterEvent.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/MediaServerRegisterEvent.java new file mode 100644 index 0000000..3f44f78 --- /dev/null +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/MediaServerRegisterEvent.java @@ -0,0 +1,27 @@ +package com.acgist.taoyao.signal.event.room; + +import com.acgist.taoyao.signal.client.Client; +import com.acgist.taoyao.signal.event.ClientEventAdapter; + +/** + * 媒体服务注册事件 + * 需要重新创建房间 + * + * 媒体服务掉线两种方案 + * + * 1. 注册相同名称媒体服务,注册成功之后通知媒体服务终端重新连接。 + * 2. 自动转移媒体服务终端到个新的媒体服务,然后通知媒体服务终端重新连接。 + * + * 本项目采用第一种方案 + * + * @author acgist + */ +public class MediaServerRegisterEvent extends ClientEventAdapter { + + private static final long serialVersionUID = 1L; + + public MediaServerRegisterEvent(Client client) { + super(client); + } + +} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomCreateEvent.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomCreateEvent.java deleted file mode 100644 index e62e991..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomCreateEvent.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.acgist.taoyao.signal.event.room; - -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.ClientEventAdapter; - -/** - * 创建房间事件 - * - * @author acgist - */ -public class RoomCreateEvent extends ClientEventAdapter { - - private static final long serialVersionUID = 1L; - - public RoomCreateEvent(Client client) { - super(client); - } - -} 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 9a5538f..b56c434 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 @@ -29,8 +29,8 @@ import lombok.extern.slf4j.Slf4j; 如果终端意外掉线,需要自己实现重连逻辑。 """, flow = { - "终端->信令服务->终端", - "终端-[关闭终端]>信令服务-[终端下线])终端", + "终端=>信令服务->终端", + "终端=>信令服务-[终端下线])终端", "终端-[连接断开]>信令服务-[终端下线])终端" } ) diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientOfflineProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientOfflineProtocol.java index d5e91ac..1cc10ae 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientOfflineProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientOfflineProtocol.java @@ -23,17 +23,20 @@ import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; "clientId": "下线终端ID" } """, - flow = "终端-[终端关闭]>信令服务-)终端" + flow = { + "终端=[关闭终端]>信令服务-[终端下线])终端", + "终端-[连接断开]>信令服务-[终端下线])终端" + } ) public class ClientOfflineProtocol extends ProtocolClientAdapter implements ApplicationListener { - - public static final String SIGNAL = "client::offline"; + + public static final String SIGNAL = "client::offline"; - public ClientOfflineProtocol() { - super("终端下线信令", SIGNAL); - } + public ClientOfflineProtocol() { + super("终端下线信令", SIGNAL); + } - @Async + @Async @Override public void onApplicationEvent(ClientOfflineEvent event) { final String clientId = event.getClientId(); diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientOnlineProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientOnlineProtocol.java index d7371f2..a0592df 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientOnlineProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientOnlineProtocol.java @@ -18,44 +18,44 @@ import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; @Description( body = """ { - "ip": "终端IP", - "name": "终端名称", - "clientId": "终端ID", - "clientType": "终端类型", - "latitude": 纬度, - "longitude": 经度, - "humidity": 湿度, - "temperature": 温度, - "signal": 信号强度(0~100), - "battery": 电池电量(0~100), - "alarming": 是否发生告警(true|false), - "charging": 是否正在充电(true|false), + "ip" : "终端IP", + "name" : "终端名称", + "clientId" : "终端ID", + "clientType" : "终端类型", + "latitude" : 纬度, + "longitude" : 经度, + "humidity" : 湿度, + "temperature" : 温度, + "signal" : 信号强度(0~100), + "battery" : 电池电量(0~100), + "alarming" : 是否发生告警(true|false), + "charging" : 是否正在充电(true|false), "clientRecording": 是否正在录像(true|false), "serverRecording": 是否正在录像(true|false), - "lastHeartbeat": "最后心跳时间", - "status": {更多状态}, - "config": {更多配置} + "lastHeartbeat" : "最后心跳时间", + "status" : {更多状态}, + "config" : {更多配置} } """, flow = "终端=[终端注册]>信令服务-)终端" ) public class ClientOnlineProtocol extends ProtocolClientAdapter implements ApplicationListener { - public static final String SIGNAL = "client::online"; - - public ClientOnlineProtocol() { - super("终端上线信令", SIGNAL); - } + public static final String SIGNAL = "client::online"; + + public ClientOnlineProtocol() { + super("终端上线信令", SIGNAL); + } - @Async + @Async @Override public void onApplicationEvent(ClientOnlineEvent event) { - final Client client = event.getClient(); + final Client client = event.getClient(); final String clientId = event.getClientId(); this.clientManager.broadcast( clientId, this.build(client.getStatus()) ); } - + } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientRebootProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientRebootProtocol.java index 2bc63c5..8008ba9 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientRebootProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientRebootProtocol.java @@ -15,17 +15,17 @@ import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; ) public class ClientRebootProtocol extends ProtocolClientAdapter { - public static final String SIGNAL = "client::reboot"; - - public ClientRebootProtocol() { - super("重启终端信令", SIGNAL); - } - - /** - * @param clientId 终端ID - */ - public void execute(String clientId) { - this.clientManager.unicast(clientId, this.build()); - } + public static final String SIGNAL = "client::reboot"; + + public ClientRebootProtocol() { + super("重启终端信令", SIGNAL); + } + + /** + * @param clientId 终端ID + */ + public void execute(String clientId) { + this.clientManager.unicast(clientId, this.build()); + } } 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 19c404a..fe58822 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 @@ -15,7 +15,7 @@ import com.acgist.taoyao.signal.client.ClientStatus; import com.acgist.taoyao.signal.client.ClientType; import com.acgist.taoyao.signal.event.client.ClientConfigEvent; import com.acgist.taoyao.signal.event.client.ClientOnlineEvent; -import com.acgist.taoyao.signal.event.room.RoomCreateEvent; +import com.acgist.taoyao.signal.event.room.MediaServerRegisterEvent; import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; import com.acgist.taoyao.signal.service.SecurityService; @@ -32,24 +32,24 @@ import lombok.extern.slf4j.Slf4j; memo = "收到注册响应之后应该设置终端的终端索引", body = """ { - "username": "信令用户", - "password": "信令密码", - "name": "终端名称", - "clientId": "终端ID", - "clientType": "终端类型", - "latitude": 纬度, - "longitude": 经度, - "humidity": 湿度, - "temperature": 温度, - "signal": 信号强度(0~100), - "battery": 电池电量(0~100), - "alarming": 是否发生告警(true|false), - "charging": 是否正在充电(true|false), + "username" : "信令用户", + "password" : "信令密码", + "name" : "终端名称", + "clientId" : "终端ID", + "clientType" : "终端类型", + "latitude" : 纬度, + "longitude" : 经度, + "humidity" : 湿度, + "temperature" : 温度, + "signal" : 信号强度(0~100), + "battery" : 电池电量(0~100), + "alarming" : 是否发生告警(true|false), + "charging" : 是否正在充电(true|false), "clientRecording": 是否正在录像(true|false), "serverRecording": 是否正在录像(true|false), - "lastHeartbeat": "最后心跳时间", - "status": {更多状态}, - "config": {更多配置} + "lastHeartbeat" : "最后心跳时间", + "status" : {更多状态}, + "config" : {更多配置} } """, flow = { @@ -60,58 +60,58 @@ import lombok.extern.slf4j.Slf4j; ) public class ClientRegisterProtocol extends ProtocolClientAdapter { - public static final String SIGNAL = "client::register"; - - private final SecurityService securityService; - - public ClientRegisterProtocol(SecurityService securityService) { - super("终端注册信令", SIGNAL); - this.securityService = securityService; - } + public static final String SIGNAL = "client::register"; + + private final SecurityService securityService; + + public ClientRegisterProtocol(SecurityService securityService) { + super("终端注册信令", SIGNAL); + this.securityService = securityService; + } @Override - public void execute(String nullClientId, ClientType nullClientType, Client client, Message message, Map body) { - final String clientId = MapUtils.get(body, Constant.CLIENT_ID); - final String username = MapUtils.get(body, Constant.USERNAME); - final String password = MapUtils.get(body, Constant.PASSWORD); - if(this.securityService.authenticate(username, password)) { - final Client oldClient = this.clientManager.getClients(clientId); - if(oldClient != null) { - log.debug("终端已经存在(注销旧的终端):{}", clientId); - CloseableUtils.close(oldClient); - } - log.info("终端注册:{}", clientId); - client.authorize(clientId); - message.setCode(MessageCode.CODE_0000); - } else { - throw MessageCodeException.of(MessageCode.CODE_3401, "注册失败"); - } - final ClientType clientType = ClientType.of(MapUtils.get(body, Constant.CLIENT_TYPE)); - // 注册响应消息 - final Message response = message.cloneWithoutBody(); - response.setBody(Map.of(Constant.INDEX, this.idService.buildClientIndex())); - client.push(response); - // 设置终端状态 - this.buildStatus(clientId, clientType, client, body); + public void execute(String nullClientId, ClientType nullClientType, Client client, Message message, Map body) { + final String clientId = MapUtils.get(body, Constant.CLIENT_ID); + final String username = MapUtils.get(body, Constant.USERNAME); + final String password = MapUtils.get(body, Constant.PASSWORD); + if(this.securityService.authenticate(username, password)) { + final Client oldClient = this.clientManager.getClients(clientId); + if(oldClient != null) { + log.debug("终端已经存在(注销旧的终端):{}", clientId); + CloseableUtils.close(oldClient); + } + log.info("终端注册:{}", clientId); + client.authorize(clientId); + message.setCode(MessageCode.CODE_0000); + } else { + throw MessageCodeException.of(MessageCode.CODE_3401, "注册失败"); + } + final ClientType clientType = ClientType.of(MapUtils.get(body, Constant.CLIENT_TYPE)); + // 注册响应消息 + final Message response = message.cloneWithoutBody(); + response.setBody(Map.of(Constant.INDEX, this.idService.buildClientIndex())); + client.push(response); + // 设置终端状态 + this.buildStatus(clientId, clientType, client, body); // 终端配置事件 - this.publishEvent(new ClientConfigEvent(client)); + this.publishEvent(new ClientConfigEvent(client)); // 终端上线事件 this.publishEvent(new ClientOnlineEvent(client)); // 媒体服务注册:创建房间事件 if(clientType.mediaServer()) { - this.publishEvent(new RoomCreateEvent(client)); + this.publishEvent(new MediaServerRegisterEvent(client)); } - } - - /** - * @param clientId 终端ID - * @param clientType 终端类型 - * @param client 终端 - * @param body 消息主体 - * - * @return 终端状态 - */ - private ClientStatus buildStatus(String clientId, ClientType clientType, Client client, Map body) { + } + + /** + * @param clientId 终端ID + * @param clientType 终端类型 + * @param client 终端 + * @param body 消息主体 + * + * @return 终端状态 + */ + private ClientStatus buildStatus(String clientId, ClientType clientType, Client client, Map body) { final ClientStatus status = client.getStatus(); status.setIp(client.getIP()); status.setName(MapUtils.get(body, Constant.NAME)); @@ -119,6 +119,6 @@ public class ClientRegisterProtocol extends ProtocolClientAdapter { status.setClientType(clientType); status.copy(body); return status; - } - + } + } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomCreateProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomCreateProtocol.java index db6561d..bd0493c 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomCreateProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomCreateProtocol.java @@ -12,7 +12,7 @@ import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.utils.MapUtils; import com.acgist.taoyao.signal.client.Client; import com.acgist.taoyao.signal.client.ClientType; -import com.acgist.taoyao.signal.event.room.RoomCreateEvent; +import com.acgist.taoyao.signal.event.room.MediaServerRegisterEvent; import com.acgist.taoyao.signal.party.room.Room; import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; @@ -41,7 +41,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; }, flow = "终端->信令服务->媒体服务->信令服务+)终端" ) -public class RoomCreateProtocol extends ProtocolClientAdapter implements ApplicationListener { +public class RoomCreateProtocol extends ProtocolClientAdapter implements ApplicationListener { public static final String SIGNAL = "room::create"; @@ -51,8 +51,9 @@ public class RoomCreateProtocol extends ProtocolClientAdapter implements Applica @Async @Override - public void onApplicationEvent(RoomCreateEvent event) { + public void onApplicationEvent(MediaServerRegisterEvent event) { this.roomManager.recreate(event.getClient(), this.build()); + // TODO:通知 } @Override