From 0f23156df12bcf0ac328da3ab52c4e882e742e14 Mon Sep 17 00:00:00 2001 From: acgist <289547414@qq.com> Date: Sat, 4 Mar 2023 23:33:40 +0800 Subject: [PATCH] =?UTF-8?q?[+]=20=E4=BC=98=E5=8C=96=E6=88=BF=E9=97=B4?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E3=80=81=E5=85=B3=E9=97=AD=E3=80=81=E5=B9=BF?= =?UTF-8?q?=E6=92=AD=E3=80=81=E7=BB=88=E7=AB=AF=E5=88=97=E8=A1=A8=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现在已经能够拉出视频 --- taoyao-client-media/src/Config.js | 2 + taoyao-client-media/src/Server.js | 22 ++-- taoyao-client-media/src/Taoyao.js | 79 +++++++++---- taoyao-client-web/src/App.vue | 19 +-- taoyao-client-web/src/components/Taoyao.js | 111 ++++++++++++------ taoyao-client-web/vite.config.js | 2 +- .../acgist/taoyao/boot/config/Constant.java | 8 +- .../configuration/BootAutoConfiguration.java | 6 +- .../acgist/taoyao/boot/utils/MapUtils.java | 36 +++++- .../taoyao/signal/client/ClientStatus.java | 12 +- .../taoyao/signal/party/media/Room.java | 2 +- .../protocol/media/MediaConsumeProtocol.java | 2 +- .../MediaTransportWebRtcCreateProtocol.java | 2 +- .../platform/PlatformScriptProtocol.java | 2 +- .../platform/PlatformShutdownProtocol.java | 2 +- .../protocol/room/RoomBroadcastProtocol.java | 5 +- .../protocol/room/RoomClientListProtocol.java | 30 +++++ .../protocol/room/RoomCloseProtocol.java | 18 ++- .../protocol/room/RoomCreateProtocol.java | 39 +++--- .../protocol/room/RoomEnterProtocol.java | 10 +- .../protocol/system/SystemInfoProtocol.java | 48 ++++++-- 21 files changed, 317 insertions(+), 140 deletions(-) diff --git a/taoyao-client-media/src/Config.js b/taoyao-client-media/src/Config.js index 3f067d5..67ac6fa 100644 --- a/taoyao-client-media/src/Config.js +++ b/taoyao-client-media/src/Config.js @@ -22,6 +22,8 @@ module.exports = { name: "桃夭媒体服务", // 地址 host: "127.0.0.1", + // host: "192.168.1.100", + // host: "192.168.8.100", // 端口 port: 8888, // 协议 diff --git a/taoyao-client-media/src/Server.js b/taoyao-client-media/src/Server.js index 0e3e824..6921cea 100644 --- a/taoyao-client-media/src/Server.js +++ b/taoyao-client-media/src/Server.js @@ -18,7 +18,7 @@ const taoyao = new Taoyao(mediasoupWorkers); * 创建Mediasoup Worker列表 */ async function buildMediasoupWorkers() { - // 可配置的事件 + // 监听事件 // mediasoup.observer.on("newworker", fn(worker)); const { workerSize } = config.mediasoup; console.info("创建Mediasoup Worker数量:", workerSize); @@ -29,16 +29,6 @@ async function buildMediasoupWorkers() { rtcMinPort: Number(config.mediasoup.workerSettings.rtcMinPort), rtcMaxPort: Number(config.mediasoup.workerSettings.rtcMaxPort), }); - worker.on("died", (error) => { - console.warn("Mediasoup Worker停止服务:", worker.pid, error); - setTimeout(() => process.exit(1), 2000); - }); - worker.observer.on("close", () => { - console.warn("Mediasoup Worker关闭服务:", worker.pid); - }); - // 可配置的事件 - // worker.observer.on("newrouter", fn(router)); - // worker.observer.on("newwebrtcserver", fn(router)); // 配置WebRTC服务 const webRtcServerOptions = JSON.parse( JSON.stringify(config.mediasoup.webRtcServerOptions) @@ -49,6 +39,16 @@ async function buildMediasoupWorkers() { const webRtcServer = await worker.createWebRtcServer(webRtcServerOptions); worker.appData.webRtcServer = webRtcServer; mediasoupWorkers.push(worker); + // 监听事件 + worker.on("died", (error) => { + console.warn("Mediasoup Worker停止服务:", worker.pid, error); + setTimeout(() => process.exit(1), 2000); + }); + worker.observer.on("close", () => { + console.warn("Mediasoup Worker关闭服务:", worker.pid); + }); + // worker.observer.on("newrouter", fn(router)); + // worker.observer.on("newwebrtcserver", fn(router)); } } diff --git a/taoyao-client-media/src/Taoyao.js b/taoyao-client-media/src/Taoyao.js index 8ae3c69..9215763 100644 --- a/taoyao-client-media/src/Taoyao.js +++ b/taoyao-client-media/src/Taoyao.js @@ -159,7 +159,7 @@ const signalChannel = { console.debug("信令通道消息:", content); me.taoyao.on(JSON.parse(content)); } catch (error) { - console.error("处理信令消息异常:", data, error); + console.error("处理信令消息异常:", data.toString(), error); } }); }); @@ -322,15 +322,18 @@ class Room { /** * 关闭资源 */ - close() { - const self = this; - if (self.close) { + closeAll() { + const me = this; + if (me.close) { return; } - self.close = true; - if (self.mediasoupRouter) { - self.mediasoupRouter.close(); - } + me.close = true; + // me.producers.forEach(v => v.close()); + // me.consumers.forEach(v => v.close()); + // me.dataProducers.forEach(v => v.close()); + // me.dataConsumers.forEach(v => v.close()); + me.transports.forEach(v => v.close()); + me.mediasoupRouter.close(); } } @@ -404,6 +407,9 @@ class Taoyao { case "room::create": this.roomCreate(message, body); break; + case "room::close": + this.roomClose(message, body); + break; } } @@ -812,8 +818,9 @@ class Taoyao { ); }); await transport.enableTraceEvent(["bwe"]); + // await transport.enableTraceEvent([ 'probation', 'bwe' ]); transport.on("trace", (trace) => { - console.debug("transport trace event:", trace, trace.type, transport.id); + console.debug("transport trace event:", transport.id, trace.type, trace); }); // 可配置的事件 // transport.on("routerclose", fn()); @@ -842,30 +849,42 @@ class Taoyao { } } + /** + * 关闭房间信令 + * + * @param {*} message 消息 + * @param {*} body 消息主体 + */ + async roomClose(message, body) { + const roomId = body.roomId; + const room = this.rooms.get(roomId); + if(!room) { + console.warn("房间无效:", roomId); + return; + } + console.info("关闭房间:", roomId); + room.closeAll(); + this.rooms.delete(roomId); + } + /** * 创建房间信令 * * @param {*} message 消息 * @param {*} body 消息主体 - * - * @returns 房间 */ async roomCreate(message, body) { + const me = this; const roomId = body.roomId; - let room = this.rooms.get(roomId); + let room = me.rooms.get(roomId); if (room) { - this.push(message); - return room; + console.debug("创建房间已经存在:", room); + me.push(message); + return; } - const mediasoupWorker = this.nextMediasoupWorker(); + const mediasoupWorker = me.nextMediasoupWorker(); const { mediaCodecs } = config.mediasoup.routerOptions; const mediasoupRouter = await mediasoupWorker.createRouter({ mediaCodecs }); - mediasoupRouter.observer.on("close", () => { - // TODO:通知房间关闭 - }); - // 可配置的事件 - // mediasoupRouter.on("workerclose", () => {}); - // mediasoupRouter.observer.on("newtransport", fn(transport)); // TODO:下面两个监控改为配置启用 const audioLevelObserver = await mediasoupRouter.createAudioLevelObserver({ maxEntries: 1, @@ -883,10 +902,22 @@ class Taoyao { audioLevelObserver, activeSpeakerObserver, }); - this.rooms.set(roomId, room); + me.rooms.set(roomId, room); console.info("创建房间", roomId); - this.push(message); - return room; + me.push(message); + // 监听事件 + mediasoupRouter.observer.on("close", () => { + console.info("房间路由关闭:", roomId, mediasoupRouter); + room.closeAll(); + me.rooms.delete(roomId); + me.push( + protocol.buildMessage("room::close", { + roomId: roomId + }) + ); + }); + // mediasoupRouter.on("workerclose", () => {}); + // mediasoupRouter.observer.on("newtransport", fn(transport)); } } diff --git a/taoyao-client-web/src/App.vue b/taoyao-client-web/src/App.vue index a239654..9b5a658 100644 --- a/taoyao-client-web/src/App.vue +++ b/taoyao-client-web/src/App.vue @@ -59,7 +59,7 @@ - + @@ -90,7 +90,7 @@ 创建房间 邀请终端 退出房间 - 关闭房间 + 关闭房间 @@ -149,14 +149,17 @@ export default { this.medias = await this.taoyao.mediaList(); }, async enterRoom() { - await this.taoyao.enterRoom(this.room.roomId); + await this.taoyao.enterRoom(this.room.roomId, this.room.password); await this.taoyao.produceMedia(); this.roomVisible = false; }, - async createRoom() { - const room = await this.taoyao.createRoom(this.room); - this.room = room; - await this.enterRoom(room.roomId); + async roomCreate() { + const room = await this.taoyao.roomCreate(this.room); + this.room.roomId = room.roomId; + await this.enterRoom(); + }, + async closeRoom() { + this.taoyao.closeRoom(); }, /** * 信令回调 diff --git a/taoyao-client-web/src/components/Taoyao.js b/taoyao-client-web/src/components/Taoyao.js index c7ed610..d2e927f 100644 --- a/taoyao-client-web/src/components/Taoyao.js +++ b/taoyao-client-web/src/components/Taoyao.js @@ -394,6 +394,7 @@ class Taoyao { }, 5000); }); } + /************************ 回调 ************************/ /** * 回调策略: * 1. 如果注册请求回调,同时执行结果返回true不再执行后面所有回调。 @@ -450,25 +451,32 @@ class Taoyao { * @param {*} message 消息 */ async postCallback(message) { - const self = this; + const me = this; switch (message.header.signal) { + case "room::client::list": + me.defaultRoomClientList(message); + break; case "client::reboot": - self.defaultClientReboot(message); + me.defaultClientReboot(message); break; case "client::shutdown": - self.defaultClientShutdown(message); + me.defaultClientShutdown(message); + break; + case "room::close": + me.defaultRoomClose(message); break; case "room::enter": - self.defaultRoomEnter(message); - break; - case "room::client::list": - self.defaultRoomClientList(message); + me.defaultRoomEnter(message); break; case "platform::error": - self.callbackError(message); + me.callbackError(message); + break; + default: + console.warn("不支持的信令:", message); break; } } + /************************ 信令 ************************/ /** * 配置默认回调 * @@ -505,6 +513,53 @@ class Taoyao { console.info("关闭终端"); window.close(); } + /** + * 房间终端列表信令 + * + * @param {*} message 消息 + */ + defaultRoomClientList(message) { + const me = this; + message.body.forEach(v => { + if (v.clientId === me.clientId) { + // 忽略自己 + } else { + me.remoteClients.set(v.clientId, me.roomId); + } + }); + } + /** + * 关闭房间信令 + * + * @param {*} message 消息 + */ + defaultRoomClose(message) { + const me = this; + const { roomId } = message.body; + if(me.roomId !== roomId) { + return; + } + console.info("关闭房间:", roomId); + me.close(); + } + /** + * 创建房间信令 + * + * @param {*} room 房间 + * + * @returns 房间 + */ + async roomCreate(room) { + const me = this; + if (!room) { + me.callbackError("无效房间"); + return; + } + const response = await me.request( + protocol.buildMessage("room::create", room) + ); + return response.body; + } defaultRoomEnter(message) { const { roomId, clientId } = message.body; if (clientId === this.clientId) { @@ -513,16 +568,6 @@ class Taoyao { this.remoteClients.set(clientId, roomId); } } - defaultRoomClientList(message) { - const self = this; - message.body.forEach((v) => { - if (v.clientId === self.clientId) { - // 忽略自己 - } else { - self.remoteClients.set(v.clientId, self.roomId); - } - }); - } /** * 错误回调 */ @@ -562,21 +607,7 @@ class Taoyao { ); return response.body; } - /** - * 创建房间 - */ - async createRoom(room) { - const self = this; - if (!room) { - this.callbackError("无效房间"); - return; - } - const response = await self.request( - protocol.buildMessage("room::create", room) - ); - return response.body; - } - async enterRoom(roomId) { + async enterRoom(roomId, password) { const self = this; if (!roomId) { this.callbackError("无效房间"); @@ -586,7 +617,7 @@ class Taoyao { self.mediasoupDevice = new mediasoupClient.Device(); const response = await self.request( protocol.buildMessage("media::router::rtp::capabilities", { - roomId: self.roomId, + roomId: self.roomId }) ); const routerRtpCapabilities = response.body.rtpCapabilities; @@ -594,6 +625,7 @@ class Taoyao { await self.request( protocol.buildMessage("room::enter", { roomId: roomId, + password: password, rtpCapabilities: self.consume ? self.mediasoupDevice.rtpCapabilities : undefined, @@ -604,6 +636,17 @@ class Taoyao { }) ); } + async closeRoom() { + const me = this; + if(!me.roomId) { + console.warn("房间无效:", me.roomId); + return; + } + me.push(protocol.buildMessage("room::close", { + roomId: me.roomId + })); + } + /************************ 媒体 ************************/ /** * 生产媒体 */ diff --git a/taoyao-client-web/vite.config.js b/taoyao-client-web/vite.config.js index 9d210ec..186a916 100644 --- a/taoyao-client-web/vite.config.js +++ b/taoyao-client-web/vite.config.js @@ -1,7 +1,7 @@ +import fs from "node:fs"; import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import { fileURLToPath, URL } from "node:url"; -import fs from "node:fs"; export default defineConfig({ plugins: [vue()], diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/Constant.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/Constant.java index 459c3b4..c088d72 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/Constant.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/Constant.java @@ -143,10 +143,6 @@ public interface Constant { * 房间ID */ String ROOM_ID = "roomId"; - /** - * 媒体服务ID - */ - String MEDIA_ID = "mediaId"; /** * 媒体流ID */ @@ -179,6 +175,10 @@ public interface Constant { * 数据消费者ID */ String DATA_CONSUMER_ID = "dataConsumerId"; + /** + * 媒体服务ID + */ + String MEDIA_CLIENT_ID = "mediaClientId"; /** * ICE服务 */ diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/configuration/BootAutoConfiguration.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/configuration/BootAutoConfiguration.java index d0c005b..4915ce9 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/configuration/BootAutoConfiguration.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/configuration/BootAutoConfiguration.java @@ -162,11 +162,11 @@ public class BootAutoConfiguration { public void init() { final Runtime runtime = Runtime.getRuntime(); final RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); + final String maxMemory = FileUtils.formatSize(runtime.maxMemory()); final String freeMemory = FileUtils.formatSize(runtime.freeMemory()); final String totalMemory = FileUtils.formatSize(runtime.totalMemory()); - final String maxMemory = FileUtils.formatSize(runtime.maxMemory()); - log.info("操作系统名称:{}", System.getProperty("os.name")); log.info("操作系统架构:{}", System.getProperty("os.arch")); + log.info("操作系统名称:{}", System.getProperty("os.name")); log.info("操作系统版本:{}", System.getProperty("os.version")); log.info("可用的处理器数量:{}", runtime.availableProcessors()); log.info("Java版本:{}", System.getProperty("java.version")); @@ -175,9 +175,9 @@ public class BootAutoConfiguration { log.info("ClassPath:{}", System.getProperty("java.class.path")); log.info("虚拟机名称:{}", System.getProperty("java.vm.name")); log.info("虚拟机参数:{}", runtimeMXBean.getInputArguments().stream().collect(Collectors.joining(" "))); + log.info("虚拟机最大内存:{}", maxMemory); log.info("虚拟机空闲内存:{}", freeMemory); log.info("虚拟机已用内存:{}", totalMemory); - log.info("虚拟机最大内存:{}", maxMemory); log.info("工作目录:{}", System.getProperty("user.dir")); log.info("用户目录:{}", System.getProperty("user.home")); log.info("临时目录:{}", System.getProperty("java.io.tmpdir")); diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/MapUtils.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/MapUtils.java index 7ba7105..cbe92c7 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/MapUtils.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/MapUtils.java @@ -1,5 +1,6 @@ package com.acgist.taoyao.boot.utils; +import java.math.BigDecimal; import java.util.Map; /** @@ -61,8 +62,35 @@ public final class MapUtils { return null; } else if(object instanceof Long value) { return value; + } else if(object instanceof Integer value) { + return value.longValue(); + } else if(object instanceof Double value) { + return value.longValue(); } - return Long.valueOf(object.toString()); + return new BigDecimal(object.toString()).longValue(); + } + + /** + * @param body 消息主体 + * @param key 参数名称 + * + * @return 参数值 + */ + public static final Double getDouble(Map body, String key) { + if(body == null) { + return null; + } + final Object object = body.get(key); + if(object == null) { + return null; + } else if(object instanceof Long value) { + return value.doubleValue(); + } else if(object instanceof Integer value) { + return value.doubleValue(); + } else if(object instanceof Double value) { + return value; + } + return new BigDecimal(object.toString()).doubleValue(); } /** @@ -78,10 +106,14 @@ public final class MapUtils { final Object object = body.get(key); if(object == null) { return null; + } else if(object instanceof Long value) { + return value.intValue(); } else if(object instanceof Integer value) { return value; + } else if(object instanceof Double value) { + return value.intValue(); } - return Integer.valueOf(object.toString()); + return new BigDecimal(object.toString()).intValue(); } /** diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientStatus.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientStatus.java index 7d5a899..ca0586f 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientStatus.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientStatus.java @@ -60,12 +60,12 @@ public class ClientStatus { * @param body 消息主体 */ public void copy(Map body) { - this.setLatitude(MapUtils.get(body, Constant.LATITUDE)); - this.setLongitude(MapUtils.get(body, Constant.LONGITUDE)); - this.setHumidity(MapUtils.get(body, Constant.HUMIDITY)); - this.setTemperature(MapUtils.get(body, Constant.TEMPERATURE)); - this.setSignal(MapUtils.get(body, Constant.SIGNAL)); - this.setBattery(MapUtils.get(body, Constant.BATTERY)); + this.setLatitude(MapUtils.getDouble(body, Constant.LATITUDE)); + this.setLongitude(MapUtils.getDouble(body, Constant.LONGITUDE)); + this.setHumidity(MapUtils.getDouble(body, Constant.HUMIDITY)); + this.setTemperature(MapUtils.getDouble(body, Constant.TEMPERATURE)); + this.setSignal(MapUtils.getInteger(body, Constant.SIGNAL)); + this.setBattery(MapUtils.getInteger(body, Constant.BATTERY)); this.setAlarming(MapUtils.getBoolean(body, Constant.ALARMING)); this.setCharging(MapUtils.getBoolean(body, Constant.CHARGING)); this.setRecording(MapUtils.getBoolean(body, Constant.RECORDING)); diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/Room.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/Room.java index b3dafea..820ed3f 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/Room.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/Room.java @@ -196,7 +196,7 @@ public class Room implements Closeable { @Override public void close() { log.info("关闭房间:{}", this.roomId); - // TODO + // TODO:关闭房间 } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaConsumeProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaConsumeProtocol.java index 1728289..3b158f8 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaConsumeProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaConsumeProtocol.java @@ -40,7 +40,7 @@ public class MediaConsumeProtocol extends ProtocolRoomAdapter implements Applica public static final String SIGNAL = "media::consume"; - protected MediaConsumeProtocol() { + public MediaConsumeProtocol() { super("消费媒体信令", SIGNAL); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportWebRtcCreateProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportWebRtcCreateProtocol.java index 351a20a..1c671bf 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportWebRtcCreateProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportWebRtcCreateProtocol.java @@ -51,7 +51,7 @@ public class MediaTransportWebRtcCreateProtocol extends ProtocolRoomAdapter { public static final String SIGNAL = "media::transport::webrtc::create"; - protected MediaTransportWebRtcCreateProtocol() { + public MediaTransportWebRtcCreateProtocol() { super("创建WebRTC通道信令", SIGNAL); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformScriptProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformScriptProtocol.java index dd1b0df..af978d5 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformScriptProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformScriptProtocol.java @@ -32,7 +32,7 @@ import lombok.extern.slf4j.Slf4j; } """ }, - flow = "终端->服务端->终端" + flow = "终端->信令服务->终端" ) public class PlatformScriptProtocol extends ProtocolClientAdapter { diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformShutdownProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformShutdownProtocol.java index f95f28b..7bf0841 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformShutdownProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformShutdownProtocol.java @@ -62,7 +62,7 @@ public class PlatformShutdownProtocol extends ProtocolClientAdapter implements C if(this.applicationContext instanceof ConfigurableApplicationContext context) { // API关闭 if(context.isActive()) { - // 如果需要完整广播可以设置延时 + // 如果需要广播完成可以设置延时 context.close(); } else { // 其他情况 diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomBroadcastProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomBroadcastProtocol.java index 2be8a34..5d6debc 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomBroadcastProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomBroadcastProtocol.java @@ -19,16 +19,17 @@ import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter; @Description( body = """ { + "roomId": "房间ID", ... } """, - flow = "终端->信令服务->终端" + flow = "终端->信令服务-)终端" ) public class RoomBroadcastProtocol extends ProtocolRoomAdapter { public static final String SIGNAL = "room::broadcast"; - protected RoomBroadcastProtocol() { + public RoomBroadcastProtocol() { super("房间广播信令", SIGNAL); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomClientListProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomClientListProtocol.java index afe2779..674bdcf 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomClientListProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomClientListProtocol.java @@ -17,6 +17,36 @@ import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter; */ @Protocol @Description( + body = { + """ + { + "roomId": "房间ID" + } + """, + """ + [ + { + "ip": "终端IP", + "name": "终端名称", + "clientId": "终端ID", + "clientType": "终端类型", + "latitude": 纬度, + "longitude": 经度, + "humidity": 湿度, + "temperature": 温度, + "signal": 信号强度(0~100), + "battery": 电池电量(0~100), + "alarming": 是否发生告警(true|false), + "charging": 是否正在充电(true|false), + "recording": 是否正在录像(true|false), + "lastHeartbeat": "最后心跳时间", + "status": {更多状态}, + "config": {更多配置} + }, + ... + ] + """ + }, flow = "终端=>信令服务->终端" ) public class RoomClientListProtocol extends ProtocolRoomAdapter { diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomCloseProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomCloseProtocol.java index 71fb86e..f56f56d 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomCloseProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomCloseProtocol.java @@ -4,6 +4,7 @@ import java.util.Map; import com.acgist.taoyao.boot.annotation.Description; import com.acgist.taoyao.boot.annotation.Protocol; +import com.acgist.taoyao.boot.config.Constant; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; import com.acgist.taoyao.signal.client.ClientType; @@ -17,6 +18,11 @@ import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter; */ @Protocol @Description( + body = """ + { + "roomId": "房间ID" + } + """, flow = "终端->信令服务->媒体服务->信令服务+)终端" ) public class RoomCloseProtocol extends ProtocolRoomAdapter { @@ -29,9 +35,15 @@ public class RoomCloseProtocol extends ProtocolRoomAdapter { @Override public void execute(String clientId, ClientType clientType, Room room, Client client, Client mediaClient, Message message, Map body) { - room.close(); - this.clientManager.broadcast(message); - // TODO:释放房间 + if(clientType == ClientType.WEB) { + mediaClient.push(this.build(Map.of(Constant.ROOM_ID, room.getRoomId()))); + } else if(clientType == ClientType.MEDIA) { + room.close(); + room.broadcast(message); + // TODO:移除 + } else { + this.logNoAdapter(clientType); + } } } 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 00ee918..840d345 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 @@ -16,25 +16,30 @@ import com.acgist.taoyao.signal.event.MediaClientRegisterEvent; import com.acgist.taoyao.signal.party.media.Room; import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; -import lombok.extern.slf4j.Slf4j; - /** * 创建房间信令 * * @author acgist */ -@Slf4j @Protocol @Description( - body = """ - { - "name": "房间名称", - "passowrd": "房间密码", - "mediaId": "媒体服务标识", - "clientSize": "终端数量" - } - """, - flow = "终端->服务端+)终端" + body = { + """ + { + "name": "房间名称", + "passowrd": "房间密码(选填)", + "mediaClientId": "媒体服务ID" + } + """, + """ + { + "name": "房间名称", + "clientSize": "终端数量", + "mediaClientId": "媒体服务ID" + } + """ + }, + flow = "终端->信令服务->媒体服务->信令服务+)终端" ) public class RoomCreateProtocol extends ProtocolClientAdapter implements ApplicationListener { @@ -53,19 +58,13 @@ public class RoomCreateProtocol extends ProtocolClientAdapter implements Applica @Override public void execute(String clientId, ClientType clientType, Client client, Message message, Map body) { if(clientType == ClientType.WEB) { - final String roomId = MapUtils.get(body, Constant.ROOM_ID); - if (roomId != null && this.roomManager.room(roomId) != null) { - log.info("房间已经存在:{}", roomId); - return; - } - // 创建房间 + // WEB同步创建房间 final Room room = this.roomManager.create( MapUtils.get(body, Constant.NAME), MapUtils.get(body, Constant.PASSWORD), - MapUtils.get(body, Constant.MEDIA_ID), + MapUtils.get(body, Constant.MEDIA_CLIENT_ID), message.cloneWithoutBody() ); - // 广播消息 message.setBody(room.getRoomStatus()); this.clientManager.broadcast(message); } else { diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomEnterProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomEnterProtocol.java index 86fc7bb..c369ad7 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomEnterProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomEnterProtocol.java @@ -2,6 +2,8 @@ package com.acgist.taoyao.signal.protocol.room; import java.util.Map; +import org.apache.commons.lang3.StringUtils; + import com.acgist.taoyao.boot.annotation.Description; import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.config.Constant; @@ -12,8 +14,8 @@ 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.party.media.ClientWrapper; -import com.acgist.taoyao.signal.party.media.Room; import com.acgist.taoyao.signal.party.media.ClientWrapper.SubscribeType; +import com.acgist.taoyao.signal.party.media.Room; import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter; import lombok.extern.slf4j.Slf4j; @@ -39,7 +41,7 @@ import lombok.extern.slf4j.Slf4j; } """ }, - flow = "终端->服务端-)终端" + flow = "终端->信令服务-)终端" ) public class RoomEnterProtocol extends ProtocolRoomAdapter { @@ -59,7 +61,7 @@ public class RoomEnterProtocol extends ProtocolRoomAdapter { final Object rtpCapabilities = MapUtils.get(body, Constant.RTP_CAPABILITIES); final Object sctpCapabilities = MapUtils.get(body, Constant.SCTP_CAPABILITIES); final String roomPassowrd = room.getPassword(); - if(roomPassowrd != null && !roomPassowrd.equals(password)) { + if(StringUtils.isNotEmpty(roomPassowrd) && !roomPassowrd.equals(password)) { throw MessageCodeException.of(MessageCode.CODE_3401, "密码错误"); } // 进入房间 @@ -74,7 +76,7 @@ public class RoomEnterProtocol extends ProtocolRoomAdapter { )); room.broadcast(message); log.info("进入房间:{} - {}", clientId, room.getRoomId()); - // 推送房间用户信息 + // 推送房间用户信息:TODO event final Message roomClientListMessage = this.roomClientListProtocol.build(); roomClientListMessage.setBody(room.clientStatus()); client.push(roomClientListMessage); diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemInfoProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemInfoProtocol.java index a4fd988..d8b9e8f 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemInfoProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemInfoProtocol.java @@ -24,7 +24,29 @@ import lombok.Setter; * @author acgist */ @Protocol -@Description +@Description( + body = """ + { + "diskspace": [ + { + "path": "存储路径", + "free": 存储空闲, + "total": 存储总量 + }, + ... + ], + "maxMemory": 最大能用内存, + "freeMemory": 空闲内存, + "totalMemory": 已用内存, + "osArch": "系统架构", + "osName": "系统名称", + "osVersion": "系统版本", + "javaVmName": "虚拟机名称", + "javaVersion": "虚拟机版本", + "cpuProcessors": CPU核心数量 + } + """ +) public class SystemInfoProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "system::info"; @@ -38,10 +60,10 @@ public class SystemInfoProtocol extends ProtocolClientAdapter { final Map info = new HashMap<>(); // 硬盘 final List diskspace = new ArrayList<>(); -// File.listRoots(); -> 不全 -// FileSystems.getDefault().getFileStores(); -> 重复 +// File.listRoots(); +// FileSystems.getDefault().getFileStores(); Stream.of(File.listRoots()).forEach(v -> { - diskspace.add(new Diskspace(v.getPath(), v.getTotalSpace(), v.getFreeSpace())); + diskspace.add(new Diskspace(v.getPath(), v.getFreeSpace(), v.getTotalSpace())); }); info.put("diskspace", diskspace); // 内存 @@ -53,8 +75,8 @@ public class SystemInfoProtocol extends ProtocolClientAdapter { info.put("freeMemoryGracefully", FileUtils.formatSize(runtime.freeMemory())); info.put("totalMemoryGracefully", FileUtils.formatSize(runtime.totalMemory())); // 其他 - info.put("osName", System.getProperty("os.name")); info.put("osArch", System.getProperty("os.arch")); + info.put("osName", System.getProperty("os.name")); info.put("osVersion", System.getProperty("os.version")); info.put("javaVmName", System.getProperty("java.vm.name")); info.put("javaVersion", System.getProperty("java.version")); @@ -71,10 +93,6 @@ public class SystemInfoProtocol extends ProtocolClientAdapter { * 路径 */ private final String path; - /** - * 总量 - */ - private final Long total; /** * 空闲 */ @@ -82,18 +100,22 @@ public class SystemInfoProtocol extends ProtocolClientAdapter { /** * 总量 */ - private final String totalGracefully; + private final Long total; /** * 空闲 */ private final String freeGracefully; + /** + * 总量 + */ + private final String totalGracefully; - public Diskspace(String path, Long total, Long free) { + public Diskspace(String path, Long free, Long total) { this.path = path; - this.total = total; this.free = free; - this.totalGracefully = FileUtils.formatSize(total); + this.total = total; this.freeGracefully = FileUtils.formatSize(free); + this.totalGracefully = FileUtils.formatSize(total); } }