From 95f2221ebb401462c8f3c499f76813404092dd71 Mon Sep 17 00:00:00 2001 From: acgist <289547414@qq.com> Date: Fri, 17 Feb 2023 07:07:56 +0800 Subject: [PATCH] =?UTF-8?q?[+]=20=E5=90=88=E5=B9=B6=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9B=91=E5=90=AC=E8=BF=98=E6=9C=89=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +- taoyao-client-web/src/components/Config.js | 3 +- .../src/components/SettingRoom.vue | 2 +- .../src/components/SettingSignal.vue | 2 +- taoyao-client-web/src/components/Taoyao.js | 177 ++++++++++++++++-- taoyao-media-server/src/Server.js | 133 ++++++------- taoyao-media-server/src/Signal.js | 45 ++++- ...{EventListener.java => EventProtocol.java} | 5 +- .../taoyao/boot/annotation/Protocol.java | 2 +- .../boot/config/BootAutoConfiguration.java | 10 +- .../taoyao/boot/property/IdProperties.java | 2 +- .../boot/property/MediaAudioProperties.java | 8 +- .../boot/property/MediaServerProperties.java | 6 +- .../acgist/taoyao/boot/service/IdService.java | 2 +- .../boot/service/impl/IdServiceImpl.java | 2 +- .../acgist/taoyao/boot/utils/HTTPUtils.java | 27 ++- .../acgist/taoyao/boot/utils/ScriptUtils.java | 62 ++++++ .../src/main/resources/application.yml | 8 +- .../acgist/taoyao/signal/WebSocketClient.java | 10 +- taoyao-signal-server/taoyao-signal/README.md | 24 +-- .../acgist/taoyao/signal/client/Client.java | 14 +- .../taoyao/signal/client/ClientAdapter.java | 26 +-- .../taoyao/signal/client/ClientManager.java | 18 +- .../taoyao/signal/client/ClientStatus.java | 18 +- .../signal/controller/ClientController.java | 12 +- .../signal/controller/RoomController.java | 12 +- .../signal/event/ClientEventAdapter.java | 4 +- .../taoyao/signal/event/RoomEventAdapter.java | 36 ++++ .../signal/event/client/ClientCloseEvent.java | 16 +- .../event/client/ClientRegisterEvent.java | 56 ------ .../event/platform/PlatformScriptEvent.java | 39 ---- .../event/platform/PlatformShutdownEvent.java | 25 --- .../signal/event/room/RoomCreateEvent.java | 56 ------ .../signal/event/room/RoomEnterEvent.java | 42 ----- .../listener/ApplicationListenerAdapter.java | 30 --- .../listener/client/ClientCloseListener.java | 53 ------ .../client/ClientRegisterListener.java | 52 ----- .../platform/PlatformScriptListener.java | 84 --------- .../platform/PlatformShutdownListener.java | 45 ----- .../listener/room/RoomCreateListener.java | 40 ---- .../listener/room/RoomEnterListener.java | 56 ------ .../taoyao/signal/media/MediaClient.java | 114 ++++++----- .../signal/media/MediaClientManager.java | 2 +- .../com/acgist/taoyao/signal/media/Peer.java | 2 +- .../com/acgist/taoyao/signal/media/Room.java | 12 +- .../taoyao/signal/media/RoomManager.java | 28 +-- .../taoyao/signal/media/RoomStatus.java | 12 +- .../acgist/taoyao/signal/media/Stream.java | 82 -------- .../acgist/taoyao/signal/media/Transport.java | 11 -- .../taoyao/signal/protocol/Constant.java | 48 +++-- .../taoyao/signal/protocol/Protocol.java | 16 +- .../signal/protocol/ProtocolAdapter.java | 9 +- .../protocol/ProtocolClientAdapter.java | 48 +++++ .../signal/protocol/ProtocolManager.java | 4 +- .../signal/protocol/ProtocolMapAdapter.java | 43 ----- .../signal/protocol/ProtocolMediaAdapter.java | 30 ++- .../protocol/ProtocolMediaRoomAdapter.java | 80 -------- .../signal/protocol/ProtocolRoomAdapter.java | 69 +++++++ .../client/ClientBroadcastProtocol.java | 8 +- .../protocol/client/ClientCloseProtocol.java | 50 ++++- .../protocol/client/ClientConfigProtocol.java | 6 +- .../client/ClientHeartbeatProtocol.java | 6 +- .../protocol/client/ClientListProtocol.java | 8 +- .../client/ClientOfflineProtocol.java | 8 +- .../protocol/client/ClientOnlineProtocol.java | 8 +- .../protocol/client/ClientRebootProtocol.java | 8 +- .../client/ClientRegisterProtocol.java | 40 +++- .../protocol/client/ClientStatusProtocol.java | 8 +- .../client/ClientUnicastProtocol.java | 6 +- .../media/AudioActiveSpeakerProtocol.java | 10 +- ...l.java => ConsumerDataStatusProtocol.java} | 2 +- .../protocol/media/MediaListProtocol.java | 6 +- .../protocol/media/MediaRebootProtocol.java | 16 +- .../protocol/media/MediaRegisterProtocol.java | 6 +- .../protocol/media/MediaShutdownProtocol.java | 36 +++- .../media/NetworkThrottleApplyProtocol.java | 5 - .../media/NetworkThrottleResetProtocol.java | 5 - .../protocol/media/PeerNewProtocol.java | 5 - .../media/RouterRtpCapabilitiesProtocol.java | 10 +- .../platform/PlatformErrorProtocol.java | 8 +- .../platform/PlatformRebootProtocol.java | 16 +- .../platform/PlatformScriptProtocol.java | 22 ++- .../platform/PlatformShutdownProtocol.java | 34 +++- .../protocol/room/RoomCloseProtocol.java | 33 +++- .../protocol/room/RoomCreateProtocol.java | 28 ++- .../protocol/room/RoomEnterProtocol.java | 37 +++- .../protocol/room/RoomListProtocol.java | 8 +- .../protocol/system/SystemRebootProtocol.java | 14 +- .../system/SystemShutdownProtocol.java | 14 +- .../service/impl/SecurityServiceImpl.java | 9 +- 90 files changed, 1098 insertions(+), 1265 deletions(-) rename taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/{EventListener.java => EventProtocol.java} (80%) create mode 100644 taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/ScriptUtils.java create mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/RoomEventAdapter.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/ClientRegisterEvent.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/PlatformScriptEvent.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/PlatformShutdownEvent.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomCreateEvent.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomEnterEvent.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/ApplicationListenerAdapter.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/ClientCloseListener.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/ClientRegisterListener.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/PlatformScriptListener.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/PlatformShutdownListener.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/room/RoomCreateListener.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/room/RoomEnterListener.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Stream.java create mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolClientAdapter.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMapAdapter.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMediaRoomAdapter.java create mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolRoomAdapter.java rename taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/{DataConsumerStatusProtocol.java => ConsumerDataStatusProtocol.java} (55%) delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/NetworkThrottleApplyProtocol.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/NetworkThrottleResetProtocol.java delete mode 100644 taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/PeerNewProtocol.java diff --git a/README.md b/README.md index ce77fab..541762c 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ |:--|:--|:--| |taoyao-client-web|终端示例|Web终端示例| |taoyao-client-android|终端示例|安卓终端示例| -|taoyao-media-server|媒体服务|Mediasoup媒体服务| -|taoyao-signal-server|信令服务|信令业务逻辑| +|taoyao-media-server|媒体服务|媒体服务| +|taoyao-signal-server|信令服务|信令服务| > 注意:只有Web实现完成信令控制,桌面还有安卓仅仅实现媒体收发。 @@ -51,10 +51,11 @@ * 录制(Recorder) * 音频:降噪、混音、变声 * 视频:水印、美颜、AI识别 +* P2P * 信令直传 * 信令服务集群 * 媒体交互式启动 -* 一个信令服务多个媒体服务 * 会议调整为房间 -* 反复测试推流拉流、拉人踢人、音频视频控制 * 内外网/多网卡环境 +* 一个信令服务多个媒体服务 +* 反复测试推流拉流、拉人踢人、音频视频控制 diff --git a/taoyao-client-web/src/components/Config.js b/taoyao-client-web/src/components/Config.js index cd4cdea..3ac7cc8 100644 --- a/taoyao-client-web/src/components/Config.js +++ b/taoyao-client-web/src/components/Config.js @@ -4,10 +4,11 @@ /** * 信令配置 + * TODO:合并到taoyao */ const config = { // 终端标识 - sn: "taoyao", + clientId: "taoyao", // 信令服务地址 host: "localhost", port: "8888", diff --git a/taoyao-client-web/src/components/SettingRoom.vue b/taoyao-client-web/src/components/SettingRoom.vue index c498a23..85d60b4 100644 --- a/taoyao-client-web/src/components/SettingRoom.vue +++ b/taoyao-client-web/src/components/SettingRoom.vue @@ -23,7 +23,7 @@ - + - + diff --git a/taoyao-client-web/src/components/Taoyao.js b/taoyao-client-web/src/components/Taoyao.js index e98051d..2a1fe71 100644 --- a/taoyao-client-web/src/components/Taoyao.js +++ b/taoyao-client-web/src/components/Taoyao.js @@ -14,6 +14,10 @@ import { // 日志 const logger = new Logger(); +const PC_PROPRIETARY_CONSTRAINTS = { + optional : [ { googDscp: true } ] +}; + /** * 信令通道 */ @@ -94,7 +98,7 @@ const signalChannel = { self.push( protocol.buildMessage("client::register", { ip: "localhost", - sn: config.sn, + clientId: config.clientId, signal: 100, battery: battery.level * 100, charging: battery.charging, @@ -284,39 +288,67 @@ const signalChannel = { */ class Taoyao { // 发送信令 - push = null; + push; + // 房间ID + roomId; // 请求信令 - request = null; + request; // 本地视频 - localVideo = null; + localVideo; // 本地终端 localClient; // 远程终端 - remoteClientList; + remoteClients = new Map(); // 媒体通道 - sendTransport = null; - recvTransport = null; + sendTransport; + recvTransport; // 信令通道 - signalChannel = null; + signalChannel; // 媒体设备 - mediasoupDevice = null; + mediasoupDevice; // 是否消费 consume = true; // 是否生产 produce = true; + // 强制使用TCP + forceTcp = false; + // 使用数据通道 + useDataChannel = true; // 是否生产音频 audioProduce = true && this.produce; // 是否生成视频 videoProduce = true && this.produce; // 音频生产者 - audioProducer = null; + audioProducer; // 视频生产者 - videoProducer = null; + videoProducer; // 消费者 consumers = new Map(); // 数据消费者 dataConsumers = new Map(); + constructor({ + roomId, + peerId, + displayName, + device, + handlerName, + useSimulcast, + useSharingSimulcast, + forceTcp, + produce, + consume, + forceH264, + forceVP9, + svc, + datachannel, + externalVideo, + e2eKey, + consumerReplicas + }) { + this.roomId = roomId; + } + /** * 打开信令通道 * @@ -338,21 +370,134 @@ class Taoyao { }; /** * 打开媒体通道 - * navigator.mediaDevices.getDisplayMedia(); + * TODO:共享 navigator.mediaDevices.getDisplayMedia(); */ buildMedia = async function (roomId) { let self = this; // 释放资源 self.closeMedia(); self.mediasoupDevice = new mediasoupClient.Device(); - const response = await this.request(protocol.buildMessage( + const response = await self.request(protocol.buildMessage( "router::rtp::capabilities", - { roomId } + { roomId : roomId || self.roomId } )); const routerRtpCapabilities = response.body; - console.log(self.mediasoupDevice); - console.log(routerRtpCapabilities); + self.mediasoupDevice.load({ routerRtpCapabilities }); + self.produce(); }; + /** + * 生产媒体 + */ + produceMedia = async function() { + // 打开媒体:TODO:参数 + const self = this; + const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video : true }); + const audioTrack = stream.getAudioTracks()[0]; + const videoTrack = stream.getVideoTracks()[0]; + if(self.produce) { + const transportInfo = await self.request("webrtc::transport::create", { + forceTcp : self.forceTcp, + producing : true, + consuming : false, + sctpCapabilities : self.useDataChannel ? self.mediasoupDevice.sctpCapabilities : undefined + }); + const { + id, + iceParameters, + iceCandidates, + dtlsParameters, + sctpParameters + } = transportInfo; + + self.sendTransport = self.mediasoupDevice.createSendTransport( + { + id, + iceParameters, + iceCandidates, + dtlsParameters : + { + ...dtlsParameters, + role : 'auto' + }, + sctpParameters, + iceServers : [], + proprietaryConstraints : PC_PROPRIETARY_CONSTRAINTS, + additionalSettings : + // TODO:加密解密 + { encodedInsertableStreams: true } + }); + + self.sendTransport.on( + 'connect', ({ dtlsParameters }, callback, errback) => + { + self.request( + 'webrtc::transport::connect', + { + transportId : self.sendTransport.id, + dtlsParameters + }) + .then(callback) + .catch(errback); + }); + + self.sendTransport.on( + 'produce', async ({ kind, rtpParameters, appData }, callback, errback) => + { + try + { + const { id } = await self.request( + 'produce', + { + transportId : self.sendTransport.id, + kind, + rtpParameters, + appData + }); + + callback({ id }); + } + catch (error) + { + errback(error); + } + }); + + sef.sendTransport.on('producedata', async ( + { + sctpStreamParameters, + label, + protocol, + appData + }, + callback, + errback + ) => + { + logger.debug( + '"producedata" event: [sctpStreamParameters:%o, appData:%o]', + sctpStreamParameters, appData); + + try + { + const { id } = await self.request( + 'produceData', + { + transportId : self.sendTransport.id, + sctpStreamParameters, + label, + protocol, + appData + }); + + callback({ id }); + } + catch (error) + { + errback(error); + } + }); + } + } /** * 关闭媒体 */ diff --git a/taoyao-media-server/src/Server.js b/taoyao-media-server/src/Server.js index a3b15f6..9243e51 100644 --- a/taoyao-media-server/src/Server.js +++ b/taoyao-media-server/src/Server.js @@ -3,7 +3,7 @@ const fs = require("fs"); const ws = require("ws"); const https = require("https"); -// const mediasoup = require("mediasoup"); +const mediasoup = require("mediasoup"); const config = require("./Config"); const Logger = require("./Logger"); const Signal = require("./Signal"); @@ -31,8 +31,8 @@ const signal = new Signal(mediasoupWorkers); */ async function buildMediasoupWorkers() { const { workerSize } = config.mediasoup; - logger.info("启动Mediasoup Worker", workerSize); - for (let i = 0; i < workerSize; i++) { + logger.info("启动Worker", workerSize); + for (let index = 0; index < workerSize; index++) { // 新建Worker const worker = await mediasoup.createWorker({ logLevel: config.mediasoup.workerSettings.logLevel, @@ -42,30 +42,23 @@ async function buildMediasoupWorkers() { }); // 监听Worker事件 worker.on("died", () => { - logger.warn("Mediasoup Worker停止服务", worker.pid); + logger.warn("Worker停止服务", worker.pid); setTimeout(() => process.exit(1), 2000); }); + worker.observer.on("close", () => { + logger.warn("Worker关闭服务", worker.pid); + }); + // 配置WebRTC服务 + const webRtcServerOptions = JSON.parse( + JSON.stringify(config.mediasoup.webRtcServerOptions) + ); + for (const listenInfo of webRtcServerOptions.listenInfos) { + listenInfo.port = listenInfo.port + mediasoupWorkers.length - 1; + } + const webRtcServer = await worker.createWebRtcServer(webRtcServerOptions); + worker.appData.webRtcServer = webRtcServer; // 加入Worker队列 mediasoupWorkers.push(worker); - // 配置WebRTC服务 - if (process.env.MEDIASOUP_USE_WEBRTC_SERVER !== "false") { - // 配置Worker端口 - const portIncrement = mediasoupWorkers.length - 1; - const webRtcServerOptions = JSON.parse( - JSON.stringify(config.mediasoup.webRtcServerOptions) - ); - for (const listenInfo of webRtcServerOptions.listenInfos) { - listenInfo.port += portIncrement; - } - // 配置WebRTC服务 - const webRtcServer = await worker.createWebRtcServer(webRtcServerOptions); - worker.appData.webRtcServer = webRtcServer; - } - // 定时记录使用日志 - setInterval(async () => { - const usage = await worker.getResourceUsage(); - logger.info("Mediasoup Worker使用情况", worker.pid, usage); - }, 120 * 1000); } } @@ -75,14 +68,14 @@ async function buildMediasoupWorkers() { async function buildSignalServer() { const tls = { cert: fs.readFileSync(config.https.tls.cert), - key: fs.readFileSync(config.https.tls.key), + key: fs.readFileSync(config.https.tls.key), }; - // 配置HTTPS + // 配置HTTPS Server httpsServer = https.createServer(tls, (request, response) => { response.writeHead(200); response.end(fs.readFileSync(config.welcome)); }); - // 配置WebSocket + // 配置WebSocket Server webSocketServer = new ws.Server({ server: httpsServer }); webSocketServer.on("connection", (session) => { logger.info("打开信令通道", session._socket.remoteAddress); @@ -115,76 +108,56 @@ async function buildSignalServer() { } /** - * 定时清理无效信令终端 + * 定时任务 */ -async function buildClientInterval() { +async function buildInterval() { + // 定时清理过期无效终端 setInterval(() => { - const datetime = Date.now(); let failSize = 0; + let silentSize = 0; let successSize = 0; - for (let i = 0; i < clients.length; i++) { - const session = clients[i]; - // 超过五秒自动关闭 - if (datetime - session.datetime >= 5000) { - clients.splice(i, 1); - if(session.authorize) { - successSize++; - } else { - failSize++; - session.close(); - } - i--; + const datetime = Date.now(); + for (let index = 0; index < clients.length; index++) { + const session = clients[index]; + if (session.authorize) { + clients.splice(index, 1); + successSize++; + index--; + } else if (datetime - session.datetime >= 5000) { + clients.splice(index, 1); + session.close(); + failSize++; + index--; + } else { + silentSize++; } } - logger.info("定时清理无效信令终端", failSize, successSize, clients.length); + logger.info("定时清理无效信令终端(无效|静默|成功|现存)", failSize, silentSize, successSize, clients.length); }, 60 * 1000); -} - -/** - * 交互式控制台 - */ -async function buildCommandConsole() { - if (!config.command) { - return; - } - process.stdin.setEncoding("UTF-8"); - process.stdin.resume(); - process.stdin.on("data", (data) => { - process.stdin.pause(); - const command = data.replace(/^\s*/, "").replace(/\s*$/, ""); - logger.info(""); - switch (command) { - case "h": - case "help": { - logger.info("- h, help : 帮助信息"); - logger.info("- os : 系统信息"); - break; - } - case "": - default: { - logger.warn(`未知命令:'${command}'`); - logger.info("查询命令:'h' | 'help'"); - break; - } + // 定时打印Worker使用情况 + setInterval(async () => { + for (const worker of mediasoupWorkers) { + const usage = await worker.getResourceUsage(); + logger.info("Worker使用情况", worker.pid, usage); } - logger.info(""); - process.stdin.resume(); - }); + }, 120 * 1000); } /** * 启动方法 */ async function main() { - logger.debug("闹市早行客"); - logger.info("江边独钓翁"); - logger.warn("山中与谁同"); - logger.error("绿竹细雨风"); + logger + .info("桃之夭夭,灼灼其华。") + .info("之子于归,宜其室家。") + .debug("DEBUG") + .info("INFO") + .warn("WARN") + .error("ERROR"); logger.info("开始启动", config.name); - // await buildMediasoupWorkers(); + await buildMediasoupWorkers(); await buildSignalServer(); - await buildClientInterval(); - await buildCommandConsole(); + await buildInterval(); logger.info("启动完成", config.name); } diff --git a/taoyao-media-server/src/Signal.js b/taoyao-media-server/src/Signal.js index 33fa594..bbe3611 100644 --- a/taoyao-media-server/src/Signal.js +++ b/taoyao-media-server/src/Signal.js @@ -31,7 +31,7 @@ const config = require("./Config"); * @returns 信令消息 */ buildMessage: function (signal, roomId, body = {}, id) { - let message = { + const message = { header: { v: config.version, id: id || this.buildId(), @@ -46,6 +46,24 @@ const config = require("./Config"); }, }; +/** + * Peer + */ +class Peer { + + peerId; + device; + displayName; + rtpCapabilities; + sctpCapabilities; + transports = new Map(); + producers = new Map(); + consumers = new Map(); + dataProducers = new Map(); + dataConsumers = new Map(); + +} + /** * 房间 */ @@ -53,6 +71,8 @@ class Room { // 是否关闭 close = false; + // 终端 + peers = new Map(); // 房间ID roomId = null; // 网络节流 @@ -104,7 +124,7 @@ class Room { } }); // 静音 - this.audioLevelObserver.on('silence', () => { + this.audioLevelObserver.on("silence", () => { this.signal.push(protocol.buildMessage( "audio::active::speaker", this.roomId, @@ -116,11 +136,18 @@ class Room { } handleActiveSpeakerObserver() { - this.activeSpeakerObserver.on('dominantspeaker', (dominantSpeaker) => { + this.activeSpeakerObserver.on("dominantspeaker", (dominantSpeaker) => { logger.debug("dominantspeaker", dominantSpeaker.producer.id); }); } + close() { + this.close = true; + if(this.mediasoupRouter) { + this.mediasoupRouter.close(); + } + } + } /** @@ -134,9 +161,9 @@ class Signal { clients = []; // 日志 logger = new Logger(); - // Mediasoup Worker列表 + // Worker列表 mediasoupWorkers = []; - // Mediasoup Worker索引 + // Worker索引 nextMediasoupWorkerIndex = 0; constructor(mediasoupWorkers) { @@ -245,7 +272,7 @@ class Signal { * @param {*} message 消息 * @param {*} body 消息主体 * - * @returns 路由 + * @returns 房间 */ async roomCreate(session, message, body) { const roomId = body.roomId; @@ -256,6 +283,12 @@ class Signal { const mediasoupWorker = this.nextMediasoupWorker(); const { mediaCodecs } = config.mediasoup.routerOptions; const mediasoupRouter = await mediasoupWorker.createRouter({ mediaCodecs }); + mediasoupRouter.on("workerclose", () => { + // TODO:通知房间关闭 + }); + mediasoupRouter.observer.on("close", () => { + // TODO:通知房间关闭 + }); // TODO:下面两个监控改为配置启用 const audioLevelObserver = await mediasoupRouter.createAudioLevelObserver({ maxEntries: 1, diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/EventListener.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/EventProtocol.java similarity index 80% rename from taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/EventListener.java rename to taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/EventProtocol.java index b8d7b67..4b5fda9 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/EventListener.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/EventProtocol.java @@ -9,8 +9,7 @@ import java.lang.annotation.Target; import org.springframework.stereotype.Component; /** - * 事件监听 - * 事件用来处理异步业务还有广播业务 + * 事件信令协议 * * @author acgist */ @@ -18,6 +17,6 @@ import org.springframework.stereotype.Component; @Component @Retention(RetentionPolicy.RUNTIME) @Documented -public @interface EventListener { +public @interface EventProtocol { } diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/Protocol.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/Protocol.java index fc31c98..68761c3 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/Protocol.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/annotation/Protocol.java @@ -9,7 +9,7 @@ import java.lang.annotation.Target; import org.springframework.stereotype.Component; /** - * 协议 + * 信令协议 * * @author acgist */ diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/BootAutoConfiguration.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/BootAutoConfiguration.java index 421d129..ec39093 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/BootAutoConfiguration.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/config/BootAutoConfiguration.java @@ -59,6 +59,7 @@ import com.acgist.taoyao.boot.service.IdService; import com.acgist.taoyao.boot.service.impl.IdServiceImpl; import com.acgist.taoyao.boot.utils.ErrorUtils; import com.acgist.taoyao.boot.utils.FileUtils; +import com.acgist.taoyao.boot.utils.HTTPUtils; import com.acgist.taoyao.boot.utils.JSONUtils; import com.fasterxml.jackson.databind.ObjectMapper; @@ -122,12 +123,17 @@ public class BootAutoConfiguration { public TaskScheduler taskScheduler(TaskSchedulerBuilder builder) { return builder.build(); } - + @Bean - public CommandLineRunner successCommandLineRunner() { + @Autowired + public CommandLineRunner successCommandLineRunner( + TaskExecutor taskExecutor, + TaoyaoProperties taoyaoProperties + ) { return new CommandLineRunner() { @Override public void run(String ... args) throws Exception { + HTTPUtils.init(taoyaoProperties.getTimeout(), taskExecutor); log.info("项目启动成功:{}", BootAutoConfiguration.this.name); } }; diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/IdProperties.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/IdProperties.java index 1edab06..e0cb249 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/IdProperties.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/IdProperties.java @@ -18,7 +18,7 @@ public class IdProperties { /** * 机器序号 */ - private Integer sn; + private Integer index; /** * 最大序号 */ diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/MediaAudioProperties.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/MediaAudioProperties.java index 89ceaae..c3690ac 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/MediaAudioProperties.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/MediaAudioProperties.java @@ -22,9 +22,13 @@ public class MediaAudioProperties { public enum Format { /** - * PCM + * PCMA */ - PCM, + PCMA, + /** + * PCMU + */ + PCMU, /** * OPUS */ diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/MediaServerProperties.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/MediaServerProperties.java index bf9a690..e48e004 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/MediaServerProperties.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/property/MediaServerProperties.java @@ -17,10 +17,10 @@ import lombok.Setter; public class MediaServerProperties { /** - * 名称 + * 媒体服务标识 */ - @Schema(title = "名称", description = "名称") - private String name; + @Schema(title = "媒体服务标识", description = "媒体服务标识") + private String mediaId; /** * 是否启用 */ diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/service/IdService.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/service/IdService.java index be3e8fc..7b7a63e 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/service/IdService.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/service/IdService.java @@ -8,7 +8,7 @@ package com.acgist.taoyao.boot.service; public interface IdService { /** - * 生成十九位的ID:YYMMddHHmmss(12) + sn(1) + xxxxxx(6) + * 生成十九位的ID:YYMMddHHmmss(12) + index(1) + xxxxxx(6) * * @return ID */ diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/service/impl/IdServiceImpl.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/service/impl/IdServiceImpl.java index 7980e3f..d3459f5 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/service/impl/IdServiceImpl.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/service/impl/IdServiceImpl.java @@ -33,7 +33,7 @@ public class IdServiceImpl implements IdService { 1000000000L * time.getMinute() + 10000000L * time.getSecond() + // 机器序号一位 - 1000000L * this.idProperties.getSn() + + 1000000L * this.idProperties.getIndex() + // 每秒并发数量 this.index; } diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/HTTPUtils.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/HTTPUtils.java index bfe7fc4..a8c245e 100644 --- a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/HTTPUtils.java +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/HTTPUtils.java @@ -6,10 +6,13 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.time.Duration; import javax.net.ssl.SSLContext; import javax.net.ssl.X509TrustManager; +import org.springframework.core.task.TaskExecutor; + import lombok.extern.slf4j.Slf4j; /** @@ -20,16 +23,38 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public final class HTTPUtils { + /** + * 超时时间 + */ + private static long timeout; + /** + * 线程池 + */ + private static TaskExecutor executor; + private HTTPUtils() { } + /** + * @param timeout 超时时间 + * @param executor 线程池 + */ + public static final void init(long timeout, TaskExecutor executor) { + HTTPUtils.timeout = timeout; + HTTPUtils.executor = executor; + } + /** * @return HTTPClient */ public static final HttpClient newClient() { return HttpClient .newBuilder() - .sslContext(buildSSLContext()) +// .version(Version.HTTP_2) + .executor(HTTPUtils.executor) + .sslContext(HTTPUtils.buildSSLContext()) + .connectTimeout(Duration.ofMillis(HTTPUtils.timeout)) +// .followRedirects(Redirect.ALWAYS) .build(); } diff --git a/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/ScriptUtils.java b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/ScriptUtils.java new file mode 100644 index 0000000..0a4d545 --- /dev/null +++ b/taoyao-signal-server/taoyao-boot/src/main/java/com/acgist/taoyao/boot/utils/ScriptUtils.java @@ -0,0 +1,62 @@ +package com.acgist.taoyao.boot.utils; + +import java.io.InputStream; + +import org.apache.commons.lang3.StringUtils; + +import com.acgist.taoyao.boot.model.MessageCode; +import com.acgist.taoyao.boot.model.MessageCodeException; + +import lombok.extern.slf4j.Slf4j; + +/** + * 脚本工具 + * + * @author acgist + */ +@Slf4j +public class ScriptUtils { + + /** + * 执行命令 + * + * @param script 命令 + * + * @return 执行结果 + */ + public static final String execute(String script) { + if(StringUtils.isEmpty(script)) { + throw MessageCodeException.of(MessageCode.CODE_1002, "无效命令:" + script); + } + String result = null; + Process process = null; + try { + process = Runtime.getRuntime().exec(script); + try( + final InputStream input = process.getInputStream(); + final InputStream error = process.getErrorStream(); + ) { + final String inputValue = new String(input.readAllBytes()); + final String errorValue = new String(input.readAllBytes()); + log.info(""" + 执行命令:{} + 执行结果:{} + 失败结果:{} + """, script, inputValue, errorValue); + result = StringUtils.isEmpty(inputValue) ? errorValue : inputValue; + } catch (Exception e) { + log.error("命令执行异常:{}", script, e); + result = e.getMessage(); + } + } catch (Exception e) { + log.error("执行命令异常:{}", script, e); + result = e.getMessage(); + } finally { + if(process != null) { + process.destroy(); + } + } + return result; + } + +} diff --git a/taoyao-signal-server/taoyao-server/src/main/resources/application.yml b/taoyao-signal-server/taoyao-server/src/main/resources/application.yml index a2903cc..9b29909 100644 --- a/taoyao-signal-server/taoyao-server/src/main/resources/application.yml +++ b/taoyao-signal-server/taoyao-server/src/main/resources/application.yml @@ -20,7 +20,7 @@ server: # context-path: /taoyao spring: profiles: - active: dev + active: local application: name: taoyao-signal-server servlet: @@ -53,7 +53,7 @@ taoyao: description: 桃夭WebRTC信令服务 timeout: 5000 id: - sn: 0 + index: 0 max-index: 999999 # 媒体配置 media: @@ -100,14 +100,14 @@ taoyao: resolution: 720*480 # 媒体服务配置 media-server-list: - - name: media-local-a + - media-id: media-local-a enabled: true host: localhost port: 4443 schema: wss username: taoyao password: taoyao - - name: media-local-z + - media-id: media-local-z enabled: true host: localhost port: 4443 diff --git a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketClient.java b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketClient.java index 490352b..a101cd7 100644 --- a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketClient.java +++ b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/WebSocketClient.java @@ -21,11 +21,11 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class WebSocketClient { - public static final WebSocket build(String uri, String sn) throws InterruptedException { - return build(uri, sn, null); + public static final WebSocket build(String uri, String clientId) throws InterruptedException { + return build(uri, clientId, null); } - public static final WebSocket build(String uri, String sn, CountDownLatch count) throws InterruptedException { + public static final WebSocket build(String uri, String clientId, CountDownLatch count) throws InterruptedException { final Object lock = new Object(); try { return HttpClient @@ -37,8 +37,8 @@ public class WebSocketClient { @Override public void onOpen(WebSocket webSocket) { webSocket.sendText(String.format(""" - {"header":{"signal":"client::register","v":"1.0.0","id":"1"},"body":{"username":"taoyao","password":"taoyao","ip":"127.0.0.1","sn":"%s"}} - """, sn), true); + {"header":{"signal":"client::register","v":"1.0.0","id":"1"},"body":{"username":"taoyao","password":"taoyao","ip":"127.0.0.1","clientId":"%s"}} + """, clientId), true); Listener.super.onOpen(webSocket); } @Override diff --git a/taoyao-signal-server/taoyao-signal/README.md b/taoyao-signal-server/taoyao-signal/README.md index 7bcb368..fa4ef07 100644 --- a/taoyao-signal-server/taoyao-signal/README.md +++ b/taoyao-signal-server/taoyao-signal/README.md @@ -7,8 +7,8 @@ "header": { "v": "版本", "id": 请求标识, - "sn": "设备标识" "signal": "信令标识", + "clientId": "设备标识" }, "code": "响应编码", "message": "响应描述", @@ -101,12 +101,12 @@ # 响应主体 [ { - "sn": "终端标识", + "clientId": "终端标识", "ip": "终端IP", "signal": 信号强度(0~100), "battery": 电池电量(0~100), "charging": 是否充电(true|false), - "mediaName": "媒体服务名称", + "mediaId": "媒体服务标识", "lastHeartbeat": "最后心跳时间" }, ... @@ -119,7 +119,7 @@ ``` # 广播主体 { - "sn": "下线终端标识" + "clientId": "下线终端标识" } # 消息流程:终端-[终端关闭]>信令服务-)终端 ``` @@ -129,12 +129,12 @@ ``` # 广播主体 { - "sn": "终端标识", + "clientId": "终端标识", "ip": "终端IP", "signal": 信号强度(0~100), "battery": 电池电量(0~100), "charging": 是否充电(true|false), - "mediaName": "媒体服务名称", + "mediaId": "媒体服务标识", "lastHeartbeat": "最后心跳时间" } # 消息流程:终端-[终端注册]>信令服务-)终端 @@ -156,7 +156,7 @@ { "username": "信令用户", "password": "信令密码", - "sn": "终端标识", + "clientId": "终端标识", "ip": "终端IP", "signal": 信号强度(0~100), "battery": 电池电量(0~100), @@ -174,16 +174,16 @@ ``` # 请求主体 { - "sn": "终端标识" + "clientId": "终端标识" } # 响应主体 { - "sn": "终端标识", + "clientId": "终端标识", "ip": "终端IP", "signal": 信号强度(0~100), "battery": 电池电量(0~100), "charging": 是否充电(true|false), - "mediaName": "媒体服务名称", + "mediaId": "媒体服务标识", "lastHeartbeat": "最后心跳时间" } # 消息流程:终端->信令服务->终端 @@ -335,7 +335,7 @@ # 广播 { "id": "房间标识", - "sn": "终端标识" + "clientId": "终端标识" } ``` @@ -393,6 +393,6 @@ ``` let socket = new WebSocket("wss://localhost:8888/websocket.signal"); -socket.send('{"header":{"signal":"client::register","v":"1.0.0","id":"1"},"body":{"username":"taoyao","password":"taoyao","sn":"taoyao"}}'); +socket.send('{"header":{"signal":"client::register","v":"1.0.0","id":"1"},"body":{"username":"taoyao","password":"taoyao","clientId":"taoyao"}}'); socket.send('{"header":{"signal":"client::heartbeat","v":"1.0.0","id":"1"},"body":{}}'); ``` \ No newline at end of file diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/Client.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/Client.java index 52f74cd..c4c1dce 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/Client.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/Client.java @@ -12,16 +12,16 @@ import com.acgist.taoyao.signal.media.MediaClient; */ public interface Client extends AutoCloseable { - /** - * @return 终端标识 - */ - String sn(); - /** * @return IP */ String ip(); + /** + * @return 终端标识 + */ + String clientId(); + /** * @return 终端状态 */ @@ -49,9 +49,9 @@ public interface Client extends AutoCloseable { /** * 设置授权 * - * @param sn 重点标识 + * @param clientId 终端标识 */ - void authorize(String sn); + void authorize(String clientId); /** * @return 是否授权 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 8979ff8..7224201 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 @@ -9,10 +9,6 @@ import com.acgist.taoyao.signal.media.MediaClient; */ public abstract class ClientAdapter implements Client { - /** - * 终端标识 - */ - protected String sn; /** * IP */ @@ -21,6 +17,10 @@ public abstract class ClientAdapter implements Client { * 进入时间 */ protected final long time; + /** + * 终端标识 + */ + protected String clientId; /** * 会话实例 */ @@ -44,17 +44,17 @@ public abstract class ClientAdapter implements Client { this.authorized = false; this.status = new ClientStatus(); } - - @Override - public String sn() { - return this.sn; - } @Override public String ip() { return this.ip; } + @Override + public String clientId() { + return this.clientId; + } + @Override public ClientStatus status() { return this.status; @@ -71,8 +71,8 @@ public abstract class ClientAdapter implements Client { } @Override - public void authorize(String sn) { - this.sn = sn; + public void authorize(String clientId) { + this.clientId = clientId; this.authorized = true; } @@ -89,7 +89,7 @@ public abstract class ClientAdapter implements Client { @Override public void mediaClient(MediaClient mediaClient) { this.mediaClient = mediaClient; - this.status.setMediaName(mediaClient.name()); + this.status.setMediaId(mediaClient.mediaId()); } @Override @@ -99,7 +99,7 @@ public abstract class ClientAdapter implements Client { @Override public String toString() { - return this.getClass().getSimpleName() + " - " + this.sn; + return this.getClass().getSimpleName() + " - " + this.clientId; } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientManager.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientManager.java index be9f03c..eb28742 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientManager.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/client/ClientManager.java @@ -56,7 +56,7 @@ public class ClientManager { */ public void unicast(String to, Message message) { this.clients().stream() - .filter(v -> Objects.equals(to, v.sn())) + .filter(v -> Objects.equals(to, v.clientId())) .forEach(v -> v.push(message)); } @@ -89,7 +89,7 @@ public class ClientManager { */ public void broadcast(String from, Message message) { this.clients().stream() - .filter(v -> !Objects.equals(from, v.sn())) + .filter(v -> !Objects.equals(from, v.clientId())) .forEach(v -> v.push(message)); } @@ -118,13 +118,13 @@ public class ClientManager { } /** - * @param sn 终端标识 + * @param clientId 终端标识 * * @return 终端列表 */ - public List clients(String sn) { + public List clients(String clientId) { return this.clients().stream() - .filter(v -> Objects.equals(sn, v.sn())) + .filter(v -> Objects.equals(clientId, v.clientId())) .toList(); } @@ -148,12 +148,12 @@ public class ClientManager { } /** - * @param sn 终端标识 + * @param clientId 终端标识 * * @return 终端状态列表 */ - public List status(String sn) { - return this.clients(sn).stream() + public List status(String clientId) { + return this.clients(clientId).stream() .map(Client::status) .toList(); } @@ -203,7 +203,7 @@ public class ClientManager { // 移除管理 this.clients.remove(client); // 关闭事件 - this.applicationContext.publishEvent(new ClientCloseEvent(null, client)); + this.applicationContext.publishEvent(new ClientCloseEvent(client)); } } } 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 222f97a..ba78ca1 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 @@ -18,11 +18,11 @@ import lombok.Setter; @Schema(title = "终端状态", description = "终端状态") public class ClientStatus { - /** - * 终端标识 - */ - @Schema(title = "终端标识", description = "终端标识") - private String sn; + /** + * 终端标识 + */ + @Schema(title = "终端标识", description = "终端标识") + private String clientId; /** * 终端IP */ @@ -44,14 +44,14 @@ public class ClientStatus { @Schema(title = "是否充电", description = "是否充电") private Boolean charging = false; /** - * 媒体服务名称 + * 媒体服务标识 */ - @Schema(title = "媒体服务名称", description = "媒体服务名称") - private String mediaName; + @Schema(title = "媒体服务标识", description = "媒体服务标识") + private String mediaId; /** * 最后心跳时间 */ @Schema(title = "最后心跳时间", description = "最后心跳时间") - private LocalDateTime lastHeartbeat = LocalDateTime.now(); + private LocalDateTime lastHeartbeat; } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java index dcfdc79..3f623e6 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java @@ -40,16 +40,16 @@ public class ClientController { } @Operation(summary = "终端状态", description = "终端状态") - @GetMapping("/status/{sn}") + @GetMapping("/status/{clientId}") @ApiResponse(content = @Content(schema = @Schema(implementation = ClientStatus.class))) - public Message status(@PathVariable String sn) { - return Message.success(this.clientManager.status(sn)); + public Message status(@PathVariable String clientId) { + return Message.success(this.clientManager.status(clientId)); } @Operation(summary = "重启终端", description = "重启终端") - @GetMapping("/reboot/{sn}") - public Message reboot(@PathVariable String sn) { - this.clientManager.unicast(sn, this.clientRebootProtocol.build()); + @GetMapping("/reboot/{clientId}") + public Message reboot(@PathVariable String clientId) { + this.clientManager.unicast(clientId, this.clientRebootProtocol.build()); return Message.success(); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/RoomController.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/RoomController.java index eafc99f..3aeb309 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/RoomController.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/RoomController.java @@ -41,17 +41,17 @@ public class RoomController { } @Operation(summary = "房间状态", description = "房间状态") - @GetMapping("/status/{id}") + @GetMapping("/status/{roomId}") @ApiResponse(content = @Content(schema = @Schema(implementation = RoomStatus.class))) - public Message status(@PathVariable Long id) { - return Message.success(this.roomManager.status(id)); + public Message status(@PathVariable Long roomId) { + return Message.success(this.roomManager.status(roomId)); } @Operation(summary = "房间终端列表", description = "房间终端列表") - @GetMapping("/list/client/{id}") + @GetMapping("/list/client/{roomId}") @ApiResponse(content = @Content(schema = @Schema(implementation = ClientStatus.class))) - public Message listClient(@PathVariable Long id) { - final Room room = this.roomManager.room(id); + public Message listClient(@PathVariable Long roomId) { + final Room room = this.roomManager.room(roomId); return Message.success(room == null ? List.of() : room.clientStatus()); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/ClientEventAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/ClientEventAdapter.java index a51e57b..041e649 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/ClientEventAdapter.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/ClientEventAdapter.java @@ -22,7 +22,7 @@ public abstract class ClientEventAdapter extends ApplicationEventAdapter { /** * 终端标识 */ - private String sn; + private String clientId; /** * 终端 */ @@ -34,7 +34,7 @@ public abstract class ClientEventAdapter extends ApplicationEventAdapter { public ClientEventAdapter(Map body, Message message, Client client) { super(body, message, client); - this.sn = client.sn(); + this.clientId = client.clientId(); this.client = client; } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/RoomEventAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/RoomEventAdapter.java new file mode 100644 index 0000000..b09245f --- /dev/null +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/RoomEventAdapter.java @@ -0,0 +1,36 @@ +package com.acgist.taoyao.signal.event; + +import java.util.Map; + +import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.signal.media.Room; + +import lombok.Getter; +import lombok.Setter; + +/** + * 房间事件适配器 + * + * @author acgist + */ +@Getter +@Setter +public class RoomEventAdapter extends ApplicationEventAdapter { + + private static final long serialVersionUID = 1L; + + /** + * 房间 + */ + private final Room room; + + public RoomEventAdapter(Message message, Room room) { + this(Map.of(), message, room); + } + + public RoomEventAdapter(Map body, Message message, Room room) { + super(body, message, room); + this.room = room; + } + +} 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 3ceed9a..810898f 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 @@ -1,25 +1,19 @@ package com.acgist.taoyao.signal.event.client; -import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; import com.acgist.taoyao.signal.event.ClientEventAdapter; -import lombok.Getter; -import lombok.Setter; - /** * 终端关闭事件 * * @author acgist */ -@Getter -@Setter public class ClientCloseEvent extends ClientEventAdapter { - - private static final long serialVersionUID = 1L; - public ClientCloseEvent(Message message, Client client) { - super(message, client); - } + private static final long serialVersionUID = 1L; + + public ClientCloseEvent(Client client) { + super(null, client); + } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/ClientRegisterEvent.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/ClientRegisterEvent.java deleted file mode 100644 index 5ca2edc..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/client/ClientRegisterEvent.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.acgist.taoyao.signal.event.client; - -import java.util.Map; - -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.ClientEventAdapter; -import com.acgist.taoyao.signal.protocol.Constant; - -import lombok.Getter; -import lombok.Setter; - -/** - * 终端注册事件 - * - * @author acgist - */ -@Getter -@Setter -public class ClientRegisterEvent extends ClientEventAdapter { - - private static final long serialVersionUID = 1L; - - public ClientRegisterEvent(Map body, Message message, Client client) { - super(body, message, client); - } - - /** - * @return {@link Constant#IP} - */ - public String getIp() { - return this.get(Constant.IP); - } - - /** - * @return {@link Constant#SIGNAL} - */ - public Integer getSignal() { - return this.get(Constant.SIGNAL); - } - - /** - * @return {@link Constant#BATTERY} - */ - public Integer getBattery() { - return this.get(Constant.BATTERY); - } - - /** - * @return {@link Constant#CHARGING} - */ - public Boolean getCharging() { - return this.get(Constant.CHARGING); - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/PlatformScriptEvent.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/PlatformScriptEvent.java deleted file mode 100644 index ce23334..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/PlatformScriptEvent.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.acgist.taoyao.signal.event.platform; - -import java.util.Map; - -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.ClientEventAdapter; -import com.acgist.taoyao.signal.protocol.Constant; - -import lombok.Getter; -import lombok.Setter; - -/** - * 执行命令事件 - * - * @author acgist - */ -@Getter -@Setter -public class PlatformScriptEvent extends ClientEventAdapter { - - private static final long serialVersionUID = 1L; - - public PlatformScriptEvent(String script, Message message, Client client) { - this(Map.of(Constant.SCRIPT, script), message, client); - } - - public PlatformScriptEvent(Map body, Message message, Client client) { - super(body, message, client); - } - - /** - * @return {@link Constant#SCRIPT} - */ - public String getScript() { - return this.get(Constant.SCRIPT); - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/PlatformShutdownEvent.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/PlatformShutdownEvent.java deleted file mode 100644 index 5867808..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/platform/PlatformShutdownEvent.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.acgist.taoyao.signal.event.platform; - -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.ClientEventAdapter; - -import lombok.Getter; -import lombok.Setter; - -/** - * 关闭平台事件 - * - * @author acgist - */ -@Getter -@Setter -public class PlatformShutdownEvent extends ClientEventAdapter { - - private static final long serialVersionUID = 1L; - - public PlatformShutdownEvent(Message message, Client client) { - super(message, 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 34b15fa..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomCreateEvent.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.acgist.taoyao.signal.event.room; - -import java.util.Map; - -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.ClientEventAdapter; -import com.acgist.taoyao.signal.protocol.Constant; - -import lombok.Getter; -import lombok.Setter; - -/** - * 创建房间事件 - * - * @author acgist - */ -@Getter -@Setter -public class RoomCreateEvent extends ClientEventAdapter { - - private static final long serialVersionUID = 1L; - - public RoomCreateEvent(Map body, Message message, Client client) { - super(body, message, client); - } - - /** - * @return {@link Constant#ID} - */ - public Long getId() { - return this.getLong(Constant.ID); - } - - /** - * @return {@link Constant#NAME} - */ - public String getName() { - return this.get(Constant.NAME); - } - - /** - * @return {@link Constant#PASSWORD} - */ - public String getPassword() { - return this.get(Constant.PASSWORD); - } - - /** - * @return {@link Constant#MEDIA_NAME} - */ - public String getMediaName() { - return this.get(Constant.MEDIA_NAME); - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomEnterEvent.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomEnterEvent.java deleted file mode 100644 index 34848ad..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/event/room/RoomEnterEvent.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.acgist.taoyao.signal.event.room; - -import java.util.Map; - -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.ClientEventAdapter; -import com.acgist.taoyao.signal.protocol.Constant; - -import lombok.Getter; -import lombok.Setter; - -/** - * 进入房间事件 - * - * @author acgist - */ -@Getter -@Setter -public class RoomEnterEvent extends ClientEventAdapter { - - private static final long serialVersionUID = 1L; - - public RoomEnterEvent(Map body, Message message, Client client) { - super(body, message, client); - } - - /** - * @return {@link Constant#ID} - */ - public Long getId() { - return this.getLong(Constant.ID); - } - - /** - * @return {@link Constant#PASSWORD} - */ - public String getPassword() { - return this.get(Constant.PASSWORD); - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/ApplicationListenerAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/ApplicationListenerAdapter.java deleted file mode 100644 index 5445edd..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/ApplicationListenerAdapter.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.acgist.taoyao.signal.listener; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationListener; - -import com.acgist.taoyao.signal.client.ClientManager; -import com.acgist.taoyao.signal.event.ClientEventAdapter; -import com.acgist.taoyao.signal.media.MediaClientManager; -import com.acgist.taoyao.signal.media.RoomManager; - -/** - * 事件监听适配器 - * - * @param 事件泛型 - * - * @author acgist - */ -public abstract class ApplicationListenerAdapter implements ApplicationListener { - - @Autowired - protected RoomManager roomManager; - @Autowired - protected ClientManager clientManager; - @Autowired - protected ApplicationContext applicationContext; - @Autowired - protected MediaClientManager mediaClientManager; - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/ClientCloseListener.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/ClientCloseListener.java deleted file mode 100644 index 5fabe5f..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/ClientCloseListener.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.acgist.taoyao.signal.listener.client; - -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Async; - -import com.acgist.taoyao.boot.annotation.EventListener; -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.client.ClientCloseEvent; -import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter; -import com.acgist.taoyao.signal.protocol.Constant; -import com.acgist.taoyao.signal.protocol.client.ClientOfflineProtocol; - -import lombok.extern.slf4j.Slf4j; - -/** - * 终端关闭监听 - * - * @author acgist - */ -@Slf4j -@EventListener -public class ClientCloseListener extends ApplicationListenerAdapter { - - @Autowired - private ClientOfflineProtocol offlineProtocol; - - @Async - @Override - public void onApplicationEvent(ClientCloseEvent event) { - final Client client = event.getClient(); - if(!client.authorized()) { - // 没有授权终端 - return; - } - final String sn = event.getSn(); - log.info("关闭终端:{}", sn); - // 房间释放 - this.roomManager.leave(client); - // 广播下线事件 - final Message message = this.offlineProtocol.build( - Map.of(Constant.SN, sn) - ); - this.clientManager.broadcast(sn, message); - // TODO:释放连接 - // TODO:释放房间 - // TODO:退出帐号 - // TODO:注意释放:是否考虑没有message(非正常的关闭)不要立即释放 - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/ClientRegisterListener.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/ClientRegisterListener.java deleted file mode 100644 index f9f3c40..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/client/ClientRegisterListener.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.acgist.taoyao.signal.listener.client; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Async; - -import com.acgist.taoyao.boot.annotation.EventListener; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.client.ClientStatus; -import com.acgist.taoyao.signal.event.client.ClientRegisterEvent; -import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter; -import com.acgist.taoyao.signal.protocol.client.ClientConfigProtocol; -import com.acgist.taoyao.signal.protocol.client.ClientOnlineProtocol; - -/** - * 终端注册监听 - * - * @author acgist - */ -@EventListener -public class ClientRegisterListener extends ApplicationListenerAdapter { - - @Autowired - private ClientConfigProtocol configProtocol; - @Autowired - private ClientOnlineProtocol onlineProtocol; - - @Async - @Override - public void onApplicationEvent(ClientRegisterEvent event) { - final Client client = event.getClient(); - if (!client.authorized()) { - return; - } - final String sn = event.getSn(); - // 下发配置 - client.push(this.configProtocol.build()); - // 终端状态 - final ClientStatus status = client.status(); - status.setSn(sn); - status.setIp(StringUtils.defaultString(client.ip(), event.getIp())); - status.setSignal(event.getSignal()); - status.setBattery(event.getBattery()); - status.setCharging(event.getCharging()); - // 上线事件 - this.clientManager.broadcast( - sn, - this.onlineProtocol.build(status) - ); - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/PlatformScriptListener.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/PlatformScriptListener.java deleted file mode 100644 index 1adb615..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/PlatformScriptListener.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.acgist.taoyao.signal.listener.platform; - -import java.io.InputStream; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.scheduling.annotation.Async; - -import com.acgist.taoyao.boot.annotation.EventListener; -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.boot.model.MessageCode; -import com.acgist.taoyao.boot.model.MessageCodeException; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.platform.PlatformScriptEvent; -import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter; -import com.acgist.taoyao.signal.protocol.Constant; - -import lombok.extern.slf4j.Slf4j; - -/** - * 执行命令监听 - * - * @author acgist - */ -@Slf4j -@EventListener -public class PlatformScriptListener extends ApplicationListenerAdapter { - - @Async - @Override - public void onApplicationEvent(PlatformScriptEvent event) { - final String sn = event.getSn(); - final Client client = event.getClient(); - final String script = event.getScript(); - final Message message = event.getMessage(); - log.debug("执行命令:{}-{}", sn, script); - final String result = this.execute(script); - message.setBody(Map.of(Constant.RESULT, result)); - client.push(message); - } - - /** - * 执行命令 - * - * @param script 命令 - * - * @return 执行结果 - */ - private String execute(String script) { - if(StringUtils.isEmpty(script)) { - throw MessageCodeException.of(MessageCode.CODE_1002, "无效命令:" + script); - } - String result = null; - Process process = null; - try { - process = Runtime.getRuntime().exec(script); - try( - final InputStream input = process.getInputStream(); - final InputStream error = process.getErrorStream(); - ) { - final String inputValue = new String(input.readAllBytes()); - final String errorValue = new String(input.readAllBytes()); - log.info(""" - 执行命令:{} - 执行结果:{} - 失败结果:{} - """, script, inputValue, errorValue); - result = StringUtils.isEmpty(inputValue) ? errorValue : inputValue; - } catch (Exception e) { - log.error("命令执行异常:{}", script, e); - result = e.getMessage(); - } - } catch (Exception e) { - log.error("执行命令异常:{}", script, e); - result = e.getMessage(); - } finally { - if(process != null) { - process.destroy(); - } - } - return result; - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/PlatformShutdownListener.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/PlatformShutdownListener.java deleted file mode 100644 index a85a46e..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/platform/PlatformShutdownListener.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.acgist.taoyao.signal.listener.platform; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; - -import com.acgist.taoyao.boot.annotation.EventListener; -import com.acgist.taoyao.boot.property.ScriptProperties; -import com.acgist.taoyao.signal.event.platform.PlatformScriptEvent; -import com.acgist.taoyao.signal.event.platform.PlatformShutdownEvent; -import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter; - -/** - * 关闭平台监听 - * - * @author acgist - */ -@EventListener -public class PlatformShutdownListener extends ApplicationListenerAdapter { - - @Autowired - private ScriptProperties scriptProperties; - @Autowired - private ApplicationContext applicationContext; - - @Override - public void onApplicationEvent(PlatformShutdownEvent event) { - if(this.applicationContext instanceof ConfigurableApplicationContext context) { - // API关闭 - if(context.isActive()) { - // 如果需要完整广播可以设置延时 - context.close(); - } else { - } - } else { - // 命令关闭 - this.applicationContext.publishEvent(new PlatformScriptEvent( - this.scriptProperties.getPlatformShutdown(), - event.getMessage(), - event.getClient() - )); - } - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/room/RoomCreateListener.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/room/RoomCreateListener.java deleted file mode 100644 index 1866718..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/room/RoomCreateListener.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.acgist.taoyao.signal.listener.room; - -import com.acgist.taoyao.boot.annotation.EventListener; -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.boot.model.MessageCodeException; -import com.acgist.taoyao.signal.event.room.RoomCreateEvent; -import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter; -import com.acgist.taoyao.signal.media.Room; - -/** - * 创建房间监听 - * - * @author acgist - */ -@EventListener -public class RoomCreateListener extends ApplicationListenerAdapter { - - @Override - public void onApplicationEvent(RoomCreateEvent event) { - final Long id = event.getId(); - if(id != null && this.roomManager.room(id) != null) { - throw MessageCodeException.of("房间已经存在"); - } - // 广播消息 - final Message message = event.getMessage(); - // 创建房间 - final Room room = this.roomManager.create( - event.getSn(), - event.getName(), - event.getPassword(), - event.getMediaName(), - message.cloneWidthoutBody() - ); - // 进入房间 - room.enter(event.getClient()); - message.setBody(room.getStatus()); - this.clientManager.broadcast(message); - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/room/RoomEnterListener.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/room/RoomEnterListener.java deleted file mode 100644 index 018c6ec..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/listener/room/RoomEnterListener.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.acgist.taoyao.signal.listener.room; - -import java.util.Map; - -import com.acgist.taoyao.boot.annotation.EventListener; -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.boot.model.MessageCode; -import com.acgist.taoyao.boot.model.MessageCodeException; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.room.RoomEnterEvent; -import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter; -import com.acgist.taoyao.signal.media.MediaClient; -import com.acgist.taoyao.signal.media.Room; -import com.acgist.taoyao.signal.protocol.Constant; - -/** - * 进入房间监听 - * - * @author acgist - */ -@EventListener -public class RoomEnterListener extends ApplicationListenerAdapter { - - @Override - public void onApplicationEvent(RoomEnterEvent event) { - final Long id = event.getId(); - final String sn = event.getSn(); - final String password = event.getPassword(); - final Room room = this.roomManager.room(id); - if(room == null) { - throw MessageCodeException.of(MessageCode.CODE_3400, "无效房间"); - } - final String roomPassowrd = room.getPassword(); - if(roomPassowrd != null && !roomPassowrd.equals(password)) { - throw MessageCodeException.of(MessageCode.CODE_3401, "密码错误"); - } - final Client client = event.getClient(); - final MediaClient mediaClient = room.getMediaClient(); - if(client.mediaClient() == null) { - client.mediaClient(mediaClient); - } else if(client.mediaClient() == mediaClient) { - } else { - throw MessageCodeException.of("不在相同媒体服务:" + mediaClient.name()); - } - // 进入房间 - room.enter(client); - // 发送通知 - final Message message = event.getMessage(); - message.setBody(Map.of( - Constant.ID, room.getId(), - Constant.SN, sn - )); - room.broadcast(message); - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/MediaClient.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/MediaClient.java index 4c31b19..97a39d4 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/MediaClient.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/MediaClient.java @@ -31,7 +31,6 @@ import com.acgist.taoyao.boot.utils.HTTPUtils; import com.acgist.taoyao.boot.utils.JSONUtils; import com.acgist.taoyao.signal.protocol.Protocol; import com.acgist.taoyao.signal.protocol.ProtocolManager; -import com.acgist.taoyao.signal.protocol.ProtocolMediaAdapter; import com.acgist.taoyao.signal.protocol.media.MediaRegisterProtocol; import lombok.extern.slf4j.Slf4j; @@ -61,9 +60,9 @@ public class MediaClient { private static final long MAX_DURATION = 60L * 1000; /** - * 名称 + * 标识 */ - private String name; + private String mediaId; /** * 重试周期 */ @@ -88,16 +87,16 @@ public class MediaClient { */ public void init(MediaServerProperties mediaServerProperties) { this.mediaServerProperties = mediaServerProperties; - this.name = mediaServerProperties.getName(); + this.mediaId = mediaServerProperties.getMediaId(); this.duration = this.taoyaoProperties.getTimeout(); this.buildClient(); } /** - * @return 名称 + * @return 标识 */ - public String name() { - return this.name; + public String mediaId() { + return this.mediaId; } /** @@ -106,10 +105,10 @@ public class MediaClient { public void heartbeat() { final CompletableFuture future = this.webSocket.sendPing(ByteBuffer.allocate(0)); try { - log.debug("心跳:{}", this.name); + log.debug("心跳:{}", this.mediaId); future.get(this.taoyaoProperties.getTimeout(), TimeUnit.MILLISECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { - log.error("心跳异常:{}", this.name, e); + log.error("心跳异常:{}", this.mediaId, e); } } @@ -126,7 +125,17 @@ public class MediaClient { .buildAsync(uri, new MessageListener()) .get(); log.info("连接媒体服务成功:{}", webSocket); - } catch (InterruptedException | ExecutionException e) { + // 关闭旧的通道 + if(this.webSocket != null && !(this.webSocket.isInputClosed() && this.webSocket.isOutputClosed())) { + this.webSocket.abort(); + } + // 设置新的通道 + this.webSocket = webSocket; + // 重置重试周期 + this.duration = this.taoyaoProperties.getTimeout(); + // 发送授权消息 + this.send(this.mediaRegisterProtocol.build(this.mediaServerProperties)); + } catch (Exception e) { log.error("连接媒体服务异常:{}", uri, e); this.taskScheduler.schedule( this::buildClient, @@ -173,24 +182,6 @@ public class MediaClient { return response; } - /** - * 打开通道 - * - * @param webSocket 通道 - */ - private void open(WebSocket webSocket) { - // 关闭旧的通道 - if(this.webSocket != null && !(this.webSocket.isInputClosed() && this.webSocket.isOutputClosed())) { - this.webSocket.abort(); - } - // 重置重试周期 - this.duration = this.taoyaoProperties.getTimeout(); - // 设置新的通道 - this.webSocket = webSocket; - // 发送授权消息 - this.send(this.mediaRegisterProtocol.build(this.mediaServerProperties)); - } - /** * @return 重试周期 */ @@ -204,38 +195,40 @@ public class MediaClient { * @param data 消息 */ private void execute(String data) { - if(StringUtils.isNotEmpty(data)) { - final Message message = JSONUtils.toJava(data, Message.class); - final Header header = message.getHeader(); - if(header == null) { - log.warn("消息格式错误(没有头部):{}", message); - return; - } - final String v = header.getV(); - final String id = header.getId(); - final String signal = header.getSignal(); - if(v == null || id == null || signal == null) { - log.warn("消息格式错误(缺失头部关键参数):{}", message); - return; - } - final Message request = this.syncMessage.get(id); - if(request != null) { - // 同步处理 - // 重新设置消息 - this.syncMessage.put(id, message); - // 唤醒等待现场 - synchronized (request) { - request.notifyAll(); - } - // 同步处理不要执行回调 - } else { - final Protocol protocol = this.protocolManager.protocol(signal); - if(protocol instanceof ProtocolMediaAdapter protocolMediaAdapter) { - protocolMediaAdapter.execute(message, this.webSocket); - } else { - log.warn("未知媒体服务信令:{}", data); - } - } + if(StringUtils.isEmpty(data)) { + log.warn("媒体服务消息格式错误:{}", data); + return; + } + final Message message = JSONUtils.toJava(data, Message.class); + final Header header = message.getHeader(); + if(header == null) { + log.warn("媒体服务消息格式错误(没有头部):{}", message); + return; + } + final String v = header.getV(); + final String id = header.getId(); + final String signal = header.getSignal(); + if(v == null || id == null || signal == null) { + log.warn("媒体服务消息格式错误(缺失头部关键参数):{}", message); + return; + } + final Message request = this.syncMessage.get(id); + if(request != null) { + // 同步处理 + // 重新设置消息 + this.syncMessage.put(id, message); + // 唤醒等待现场 + synchronized (request) { + request.notifyAll(); + } + // 同步处理不要执行回调 + } else { + final Protocol protocol = this.protocolManager.protocol(signal); + if(protocol == null) { + log.warn("未知媒体服务信令:{}", message); + } else { + protocol.execute(this, message); + } } } @@ -250,7 +243,6 @@ public class MediaClient { public void onOpen(WebSocket webSocket) { log.info("媒体服务通道打开:{}", webSocket); Listener.super.onOpen(webSocket); - MediaClient.this.open(webSocket); } @Override diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/MediaClientManager.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/MediaClientManager.java index 1c6af27..11257cf 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/MediaClientManager.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/MediaClientManager.java @@ -45,7 +45,7 @@ public class MediaClientManager { .forEach(v -> { final MediaClient client = this.applicationContext.getBean(MediaClient.class); client.init(v); - this.clientMap.put(client.name(), client); + this.clientMap.put(client.mediaId(), client); log.info("注册媒体服务终端:{}-{}", v.getAddress(), client); }); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Peer.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Peer.java index 2221a8d..c49f90b 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Peer.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Peer.java @@ -20,9 +20,9 @@ public class Peer { * 终端会话 */ private Client client; + private String device; private String produce; private String consume; - private String device; private String rtpCapabilities; private String sctpCapabilities; private Map transports; diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Room.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Room.java index 9891379..38ed1a7 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Room.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Room.java @@ -25,7 +25,7 @@ public class Room implements Closeable { /** * ID */ - private Long id; + private Long roomId; /** * 密码 */ @@ -67,7 +67,7 @@ public class Room implements Closeable { return; } if(this.clients.add(client)) { - this.status.setSnSize(this.status.getSnSize() + 1); + this.status.setClientSize(this.status.getClientSize() + 1); } } } @@ -80,7 +80,7 @@ public class Room implements Closeable { public void leave(Client client) { synchronized (this.clients) { if(this.clients.remove(client)) { - this.status.setSnSize(this.status.getSnSize() - 1); + this.status.setClientSize(this.status.getClientSize() - 1); } } } @@ -102,7 +102,7 @@ public class Room implements Closeable { */ public void broadcast(String from, Message message) { this.clients.stream() - .filter(v -> !Objects.equals(from, v.sn())) + .filter(v -> !Objects.equals(from, v.clientId())) .forEach(v -> v.push(message)); } @@ -134,8 +134,8 @@ public class Room implements Closeable { @Override public void close() { - log.info("关闭房间:{}", this.id); - this.transports.forEach(Transport::close); + log.info("关闭房间:{}", this.roomId); + this.mediaClient.send(null); } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/RoomManager.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/RoomManager.java index 5596729..5450c6f 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/RoomManager.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/RoomManager.java @@ -36,13 +36,13 @@ public class RoomManager { private List rooms = new CopyOnWriteArrayList<>(); /** - * @param id ID + * @param roomId ID * * @return 房间信息 */ - public Room room(Long id) { + public Room room(Long roomId) { return this.rooms.stream() - .filter(v -> Objects.equals(id, v.getId())) + .filter(v -> Objects.equals(roomId, v.getRoomId())) .findFirst() .orElse(null); } @@ -55,12 +55,12 @@ public class RoomManager { } /** - * @param id ID + * @param roomId ID * * @return 房间信息 */ - public RoomStatus status(Long id) { - final Room room = this.room(id); + public RoomStatus status(Long roomId) { + final Room room = this.room(roomId); return room == null ? null : room.getStatus(); } @@ -76,29 +76,29 @@ public class RoomManager { /** * 创建房间 * - * @param sn 创建终端标识 + * @param clientId 创建终端标识 * @param name 名称 * @param password 密码 - * @param mediaName 媒体服务名称 + * @param mediaId 媒体服务标识 * @param message 创建消息 * * @return 房间信息 */ - public Room create(String sn, String name, String password, String mediaName, Message message) { - final MediaClient mediaClient = this.mediaClientManager.mediaClient(mediaName); + public Room create(String clientId, String name, String password, String mediaId, Message message) { + final MediaClient mediaClient = this.mediaClientManager.mediaClient(mediaId); if(mediaClient == null) { - throw MessageCodeException.of("无效媒体服务:" + mediaName); + throw MessageCodeException.of("无效媒体服务:" + mediaId); } final Long id = this.idService.buildId(); // 状态 final RoomStatus roomStatus = new RoomStatus(); roomStatus.setId(id); roomStatus.setName(name); - roomStatus.setSnSize(0L); - roomStatus.setMediaName(mediaName); + roomStatus.setMediaId(mediaId); + roomStatus.setClientSize(0L); // 房间 final Room room = new Room(); - room.setId(id); + room.setRoomId(id); room.setPassword(password); room.setStatus(roomStatus); room.setMediaClient(mediaClient); diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/RoomStatus.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/RoomStatus.java index f93dadb..564f339 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/RoomStatus.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/RoomStatus.java @@ -23,15 +23,15 @@ public class RoomStatus { */ @Schema(title = "名称", description = "名称") private String name; + /** + * 媒体服务标识 + */ + @Schema(title = "媒体服务标识", description = "媒体服务标识") + private String mediaId; /** * 终端数量 */ @Schema(title = "终端数量", description = "终端数量") - private Long snSize; - /** - * 媒体服务名称 - */ - @Schema(title = "媒体服务名称", description = "媒体服务名称") - private String mediaName; + private Long clientSize; } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Stream.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Stream.java deleted file mode 100644 index 2d550a6..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Stream.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.acgist.taoyao.signal.media; - -import java.io.Closeable; - -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -/** - * 终端媒体流 - * - * @author acgist - */ -@Slf4j -@Getter -@Setter -public class Stream implements Closeable { - - /** - * 媒体类型 - * - * @author acgist - */ - public enum Kind { - - /** - * 音频 - */ - AUDIO, - /** - * 视频 - */ - VIDEO; - - } - - /** - * 收发类型 - * - * @author acgist - */ - public enum Type { - - /** - * 发送 - */ - SEND, - /** - * 接收 - */ - RECV; - - } - - /** - * 媒体终端标识 - */ - private String sn; - /** - * 媒体流ID - * - * 媒体类型.发送终端标识.发送.房间ID: - * 音频:audio.sn.send.1000 - * 视频:video.sn.send.1000 - * - * 媒体类型.接收终端标识.接收.发送终端标识.房间ID: - * 音频:audio.sn.recv.sn.1000 - * 视频:video.sn.recv.sn.1000 - */ - private String streamId; - /** - * 媒体流描述 - */ - private String description; - - @Override - public void close() { - log.info("关闭媒体:{}", this.streamId); - // TODO:发送 - } - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Transport.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Transport.java index d14273b..e35c20d 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Transport.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/Transport.java @@ -1,7 +1,6 @@ package com.acgist.taoyao.signal.media; import java.io.Closeable; -import java.util.List; import com.acgist.taoyao.signal.client.Client; @@ -16,19 +15,9 @@ public class Transport implements Closeable { * 终端 */ private Client client; - /** - * 生产者列表 - */ - private List producers; - /** - * 消费者列表 - */ - private List consumers; @Override public void close() { - this.producers.forEach(Stream::close); - this.consumers.forEach(Stream::close); } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Constant.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Constant.java index 0807100..c092d8b 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Constant.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Constant.java @@ -7,18 +7,14 @@ package com.acgist.taoyao.signal.protocol; */ public interface Constant { - /** - * ID - */ - String ID = "id"; + /** + * 换行 + */ + String LINE = "\n"; /** * IP */ String IP = "ip"; - /** - * 终端标识 - */ - String SN = "sn"; /** * 接收方 */ @@ -39,10 +35,6 @@ public interface Constant { * 是否充电 */ String CHARGING = "charging"; - /** - * 媒体服务名称 - */ - String MEDIA_NAME = "mediaName"; /** * 名称 */ @@ -75,12 +67,24 @@ public interface Constant { * WebRTC */ String WEBRTC = "webrtc"; + /** + * PeerId + * + * @see #CLIENT_ID + */ + String PEER_ID = "peerId"; /** * 房间ID */ String ROOM_ID = "roomId"; + /** + * 媒体服务ID + */ + String MEDIA_ID = "mediaId"; /** * 终端ID + * + * @see #PEER_ID */ String CLIENT_ID = "clientId"; /** @@ -88,12 +92,24 @@ public interface Constant { */ String ROUTER_ID = "routerId"; /** - * 终端ID + * 传输通道ID */ - String STREAM_ID = "streamId"; + String TRANSPORT_ID = "transportId"; /** - * 换行 + * 生产者ID */ - String LINE = "\n"; + String PRODUCER_ID = "producerId"; + /** + * 消费者ID + */ + String CONSUMER_ID = "consumerId"; + /** + * 数据生产者ID + */ + String DATA_PRODUCER_ID = "dataProducerId"; + /** + * 数据消费者ID + */ + String DATA_CONSUMER_ID = "dataConsumerId"; } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Protocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Protocol.java index d60c901..5a4743e 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Protocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/Protocol.java @@ -3,7 +3,8 @@ package com.acgist.taoyao.signal.protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.model.MessageCode; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.ClientEventAdapter; +import com.acgist.taoyao.signal.event.ApplicationEventAdapter; +import com.acgist.taoyao.signal.media.MediaClient; /** * 信令协议 @@ -42,11 +43,18 @@ public interface Protocol { /** * 处理信令消息 * - * @param sn 终端标识 * @param client 终端 * @param message 信令消息 */ - void execute(String sn, Client client, Message message); + void execute(Client client, Message message); + + /** + * 处理媒体信令消息 + * + * @param mediaClient 媒体服务终端 + * @param message 信令消息 + */ + void execute(MediaClient mediaClient, Message message); /** * 发布事件 @@ -55,7 +63,7 @@ public interface Protocol { * * @param event 事件 */ - void publishEvent(E event); + void publishEvent(E event); /** * 创建信令消息 diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolAdapter.java index 0161609..390daa8 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolAdapter.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolAdapter.java @@ -9,17 +9,18 @@ import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.model.MessageCode; import com.acgist.taoyao.boot.property.TaoyaoProperties; import com.acgist.taoyao.boot.service.IdService; +import com.acgist.taoyao.signal.MapBodyGetter; import com.acgist.taoyao.signal.client.ClientManager; -import com.acgist.taoyao.signal.event.ClientEventAdapter; +import com.acgist.taoyao.signal.event.ApplicationEventAdapter; import com.acgist.taoyao.signal.media.MediaClientManager; import com.acgist.taoyao.signal.media.RoomManager; /** - * 信令适配器 + * 信令协议适配器 * * @author acgist */ -public abstract class ProtocolAdapter implements Protocol { +public abstract class ProtocolAdapter implements Protocol, MapBodyGetter { @Autowired protected IdService idService; @@ -59,7 +60,7 @@ public abstract class ProtocolAdapter implements Protocol { } @Override - public void publishEvent(E event) { + public void publishEvent(E event) { this.applicationContext.publishEvent(event); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolClientAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolClientAdapter.java new file mode 100644 index 0000000..967314e --- /dev/null +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolClientAdapter.java @@ -0,0 +1,48 @@ +package com.acgist.taoyao.signal.protocol; + +import java.util.Map; + +import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.boot.model.MessageCodeException; +import com.acgist.taoyao.signal.client.Client; +import com.acgist.taoyao.signal.media.MediaClient; + +/** + * 终端信令协议适配器 + * + * @author acgist + */ +public abstract class ProtocolClientAdapter extends ProtocolAdapter { + + protected ProtocolClientAdapter(String name, String signal) { + super(name, signal); + } + + @Override + public void execute(Client client, Message message) { + final Object body = message.getBody(); + if(body instanceof Map map) { + this.execute(client.clientId(), map, client, message); + } else if(body == null) { + this.execute(client.clientId(), Map.of(), client, message); + } else { + throw MessageCodeException.of("信令主体类型错误:" + message); + } + } + + @Override + public void execute(MediaClient mediaClient, Message message) { + // 忽略 + } + + /** + * 处理信令 + * + * @param clientId 终端标识 + * @param body 消息主体 + * @param client 终端 + * @param message 信令消息 + */ + public abstract void execute(String clientId, Map body, Client client, Message message); + +} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolManager.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolManager.java index 7a3a672..e07d4fd 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolManager.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolManager.java @@ -115,9 +115,9 @@ public class ProtocolManager { return; } if(protocol instanceof ClientRegisterProtocol) { - protocol.execute(null, client, message); + protocol.execute(client, message); } else if(this.securityService.authenticate(message, client, protocol)) { - protocol.execute(client.sn(), client, message); + protocol.execute(client, message); } else { log.warn("终端会话没有授权:{}", content); client.push(this.platformErrorProtocol.build(MessageCode.CODE_3401, "终端会话没有授权")); diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMapAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMapAdapter.java deleted file mode 100644 index c7eff23..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMapAdapter.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.acgist.taoyao.signal.protocol; - -import java.util.Map; - -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.boot.model.MessageCodeException; -import com.acgist.taoyao.signal.MapBodyGetter; -import com.acgist.taoyao.signal.client.Client; - -/** - * Map消息主体信令适配器 - * - * @author acgist - */ -public abstract class ProtocolMapAdapter extends ProtocolAdapter implements MapBodyGetter { - - protected ProtocolMapAdapter(String name, String signal) { - super(name, signal); - } - - @Override - public void execute(String sn, Client client, Message message) { - final Object body = message.getBody(); - if(body instanceof Map map) { - this.execute(sn, map, client, message); - } else if(body == null) { - this.execute(sn, Map.of(), client, message); - } else { - throw MessageCodeException.of("信令主体类型错误:" + message); - } - } - - /** - * 处理信令消息 - * - * @param sn 终端标识 - * @param body 消息主体 - * @param client 终端 - * @param message 信令消息 - */ - public abstract void execute(String sn, Map body, Client client, Message message); - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMediaAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMediaAdapter.java index 9cb8a30..b0895f2 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMediaAdapter.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMediaAdapter.java @@ -1,15 +1,17 @@ package com.acgist.taoyao.signal.protocol; -import java.net.http.WebSocket; +import java.util.Map; import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.boot.model.MessageCodeException; +import com.acgist.taoyao.signal.media.MediaClient; /** - * 媒体服务信令适配器 + * 媒体服务信令协议适配器 * * @author acgist */ -public abstract class ProtocolMediaAdapter extends ProtocolAdapter { +public abstract class ProtocolMediaAdapter extends ProtocolClientAdapter { protected ProtocolMediaAdapter(String name, String signal) { super(name, signal); @@ -18,9 +20,27 @@ public abstract class ProtocolMediaAdapter extends ProtocolAdapter { /** * 处理媒体服务信令 * + * @param mediaClient 媒体服务终端 * @param message 信令消息 - * @param webSocket WebSocket */ - public abstract void execute(Message message, WebSocket webSocket); + public void execute(MediaClient mediaClient, Message message) { + final Object body = message.getBody(); + if(body instanceof Map map) { + this.execute(map, mediaClient, message); + } else if(body == null) { + this.execute(Map.of(), mediaClient, message); + } else { + throw MessageCodeException.of("信令主体类型错误:" + message); + } + } + + /** + * 处理媒体服务信令 + * + * @param body 信令主体 + * @param mediaClient 媒体服务终端 + * @param message 信令消息 + */ + public abstract void execute(Map body, MediaClient mediaClient, Message message); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMediaRoomAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMediaRoomAdapter.java deleted file mode 100644 index 82d3a5d..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolMediaRoomAdapter.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.acgist.taoyao.signal.protocol; - -import java.net.http.WebSocket; -import java.util.Map; - -import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.boot.model.MessageCodeException; -import com.acgist.taoyao.signal.MapBodyGetter; -import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.media.Room; - -/** - * 房间媒体服务信令适配器 - * - * TODO:校验是否是房间内的用户权限 - * - * @author acgist - */ -public abstract class ProtocolMediaRoomAdapter extends ProtocolMediaAdapter implements MapBodyGetter { - - protected ProtocolMediaRoomAdapter(String name, String signal) { - super(name, signal); - } - - @Override - public void execute(Message message, WebSocket webSocket) { - final Object body = message.getBody(); - if(body instanceof Map map) { - this.execute(this.room(map), map, message, webSocket); - } else { - throw MessageCodeException.of("信令主体类型错误:" + message); - } - } - - @Override - public void execute(String sn, Client client, Message message) { - final Object body = message.getBody(); - if(body instanceof Map map) { - this.execute(sn, this.room(map), map, client, message); - } else { - throw MessageCodeException.of("信令主体类型错误:" + message); - } - } - - /** - * @param map 参数 - * - * @return 房间 - */ - protected Room room(Map map) { - final Long roomId = this.getLong(map, Constant.ROOM_ID); - final Room room = this.roomManager.room(roomId); - if(room == null) { - throw MessageCodeException.of("房间无效:" + roomId); - } - return room; - } - - /** - * 处理房间信令 - * - * @param room 房间 - * @param body 消息 - * @param message 信令消息 - * @param webSocket WebSocket - */ - public abstract void execute(Room room, Map body, Message message, WebSocket webSocket); - - /** - * 处理终端信令 - * - * @param sn 终端标识 - * @param room 房间 - * @param body 消息 - * @param client 终端 - * @param message 信令消息 - */ - public abstract void execute(String sn, Room room, Map body, Client client, Message message); - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolRoomAdapter.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolRoomAdapter.java new file mode 100644 index 0000000..a842e29 --- /dev/null +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/ProtocolRoomAdapter.java @@ -0,0 +1,69 @@ +package com.acgist.taoyao.signal.protocol; + +import java.util.Map; + +import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.boot.model.MessageCodeException; +import com.acgist.taoyao.signal.client.Client; +import com.acgist.taoyao.signal.media.MediaClient; +import com.acgist.taoyao.signal.media.Room; + +/** + * 房间信令协议适配器 + * + * TODO:校验是否是房间内的用户权限 + * + * @author acgist + */ +public abstract class ProtocolRoomAdapter extends ProtocolMediaAdapter { + + protected ProtocolRoomAdapter(String name, String signal) { + super(name, signal); + } + + @Override + public void execute(Map body, MediaClient mediaClient, Message message) { + this.execute(this.room(body), body, mediaClient, message); + } + + @Override + public void execute(String clientId, Map body, Client client, Message message) { + this.execute(clientId, this.room(body), body, client, message); + } + + /** + * @param body 信令主体 + * + * @return 房间 + */ + protected Room room(Map body) { + final Long roomId = this.getLong(body, Constant.ROOM_ID); + final Room room = this.roomManager.room(roomId); + if(room == null) { + throw MessageCodeException.of("房间无效:" + roomId); + } + return room; + } + + /** + * 处理房间信令 + * + * @param room 房间 + * @param body 消息 + * @param mediaClient 媒体服务终端 + * @param message 信令消息 + */ + public abstract void execute(Room room, Map body, MediaClient mediaClient, Message message); + + /** + * 处理终端信令 + * + * @param clientId 终端标识 + * @param room 房间 + * @param body 消息 + * @param client 终端 + * @param message 信令消息 + */ + public abstract void execute(String clientId, Room room, Map body, Client client, Message message); + +} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientBroadcastProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientBroadcastProtocol.java index cb7a3f5..898f3b9 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientBroadcastProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientBroadcastProtocol.java @@ -1,9 +1,11 @@ package com.acgist.taoyao.signal.protocol.client; +import java.util.Map; + import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 终端广播信令 @@ -11,7 +13,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolAdapter; * @author acgist */ @Protocol -public class ClientBroadcastProtocol extends ProtocolAdapter { +public class ClientBroadcastProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::broadcast"; @@ -20,7 +22,7 @@ public class ClientBroadcastProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { this.clientManager.broadcast(client, message); } 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 6d4ea6b..118682b 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 @@ -1,9 +1,16 @@ package com.acgist.taoyao.signal.protocol.client; -import com.acgist.taoyao.boot.annotation.Protocol; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; + +import com.acgist.taoyao.boot.annotation.EventProtocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.event.client.ClientCloseEvent; +import com.acgist.taoyao.signal.protocol.Constant; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; import lombok.extern.slf4j.Slf4j; @@ -13,17 +20,25 @@ import lombok.extern.slf4j.Slf4j; * @author acgist */ @Slf4j -@Protocol -public class ClientCloseProtocol extends ProtocolAdapter { +@EventProtocol +public class ClientCloseProtocol extends ProtocolClientAdapter implements ApplicationListener { public static final String SIGNAL = "client::close"; + @Autowired + private ClientOfflineProtocol offlineProtocol; + public ClientCloseProtocol() { super("终端关闭信令", SIGNAL); } + + @Override + public void onApplicationEvent(ClientCloseEvent event) { + this.close(event.getClient()); + } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { // 响应消息 client.push(message.cloneWidthoutBody()); // 不用发布事件:关闭连接后会发布事件 @@ -33,5 +48,30 @@ public class ClientCloseProtocol extends ProtocolAdapter { log.error("关闭终端异常", e); } } + + /** + * 关闭终端 + * + * @param client 终端 + */ + public void close(Client client) { + if(!client.authorized()) { + // 没有授权终端 + return; + } + final String clientId = client.clientId(); + log.info("关闭终端:{}", clientId); + // 房间释放 + this.roomManager.leave(client); + // 广播下线事件 + final Message message = this.offlineProtocol.build( + Map.of(Constant.CLIENT_ID, clientId) + ); + this.clientManager.broadcast(clientId, message); + // TODO:释放连接 + // TODO:释放房间 + // TODO:退出帐号 + // TODO:注意释放:是否考虑没有message(非正常的关闭)不要立即释放 + } } 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 bf03095..11f0cd0 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 @@ -12,7 +12,7 @@ import com.acgist.taoyao.boot.property.WebrtcProperties; import com.acgist.taoyao.boot.utils.DateUtils.DateTimeStyle; import com.acgist.taoyao.signal.client.Client; import com.acgist.taoyao.signal.protocol.Constant; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 终端配置信令 @@ -20,7 +20,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolAdapter; * @author acgist */ @Protocol -public class ClientConfigProtocol extends ProtocolAdapter { +public class ClientConfigProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::config"; @@ -34,7 +34,7 @@ public class ClientConfigProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { // 忽略 } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientHeartbeatProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientHeartbeatProtocol.java index dfc8711..06f87f3 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientHeartbeatProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientHeartbeatProtocol.java @@ -8,7 +8,7 @@ import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; import com.acgist.taoyao.signal.client.ClientStatus; import com.acgist.taoyao.signal.protocol.Constant; -import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 终端心跳信令 @@ -16,7 +16,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; * @author acgist */ @Protocol -public class ClientHeartbeatProtocol extends ProtocolMapAdapter { +public class ClientHeartbeatProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::heartbeat"; @@ -25,7 +25,7 @@ public class ClientHeartbeatProtocol extends ProtocolMapAdapter { } @Override - public void execute(String sn, Map body, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { // 响应心跳 client.push(message.cloneWidthoutBody()); // 设置状态 diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientListProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientListProtocol.java index 326fa58..8dd39d5 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientListProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientListProtocol.java @@ -1,9 +1,11 @@ package com.acgist.taoyao.signal.protocol.client; +import java.util.Map; + import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 终端列表信令 @@ -11,7 +13,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolAdapter; * @author acgist */ @Protocol -public class ClientListProtocol extends ProtocolAdapter { +public class ClientListProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::list"; @@ -20,7 +22,7 @@ public class ClientListProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { message.setBody(this.clientManager.status()); client.push(message); } 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 558f760..fe933ff 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 @@ -1,9 +1,11 @@ package com.acgist.taoyao.signal.protocol.client; +import java.util.Map; + import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 终端下线信令 @@ -11,7 +13,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolAdapter; * @author acgist */ @Protocol -public class ClientOfflineProtocol extends ProtocolAdapter { +public class ClientOfflineProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::offline"; @@ -20,7 +22,7 @@ public class ClientOfflineProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { // 忽略 } 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 5554d26..988218c 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 @@ -1,9 +1,11 @@ package com.acgist.taoyao.signal.protocol.client; +import java.util.Map; + import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 终端上线信令 @@ -11,7 +13,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolAdapter; * @author acgist */ @Protocol -public class ClientOnlineProtocol extends ProtocolAdapter { +public class ClientOnlineProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::online"; @@ -20,7 +22,7 @@ public class ClientOnlineProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { // 忽略 } 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 a8ac1eb..d5d199c 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 @@ -1,9 +1,11 @@ package com.acgist.taoyao.signal.protocol.client; +import java.util.Map; + import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 重启终端信令 @@ -11,7 +13,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolAdapter; * @author acgist */ @Protocol -public class ClientRebootProtocol extends ProtocolAdapter { +public class ClientRebootProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::reboot"; @@ -20,7 +22,7 @@ public class ClientRebootProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message 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 e71c1f1..b5390fb 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 @@ -1,16 +1,19 @@ package com.acgist.taoyao.signal.protocol.client; +import java.time.LocalDateTime; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.model.MessageCode; +import com.acgist.taoyao.boot.model.MessageCodeException; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.client.ClientRegisterEvent; +import com.acgist.taoyao.signal.client.ClientStatus; import com.acgist.taoyao.signal.protocol.Constant; -import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; import com.acgist.taoyao.signal.service.SecurityService; import lombok.extern.slf4j.Slf4j; @@ -22,34 +25,51 @@ import lombok.extern.slf4j.Slf4j; */ @Slf4j @Protocol -public class ClientRegisterProtocol extends ProtocolMapAdapter { +public class ClientRegisterProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::register"; @Autowired private SecurityService securityService; + @Autowired + private ClientConfigProtocol configProtocol; + @Autowired + private ClientOnlineProtocol onlineProtocol; public ClientRegisterProtocol() { super("终端注册信令", SIGNAL); } @Override - public void execute(String sn, Map body, Client client, Message message) { - final String clientSn = this.get(body, Constant.SN); + public void execute(String nullClientId, Map body, Client client, Message message) { + final String clientId = this.get(body, Constant.CLIENT_ID); final String username = this.get(body, Constant.USERNAME); final String password = this.get(body, Constant.PASSWORD); // 如果需要终端鉴权在此实现 if(this.securityService.authenticate(username, password)) { - log.info("终端注册:{}", clientSn); - client.authorize(clientSn); + log.info("终端注册:{}", clientId); + client.authorize(clientId); message.setCode(MessageCode.CODE_0000); } else { - message.setCode(MessageCode.CODE_3401); + throw MessageCodeException.of(MessageCode.CODE_3401, "注册失败"); } // 推送消息 client.push(message.cloneWidthoutBody()); - // 发送事件 - this.publishEvent(new ClientRegisterEvent(body, message, client)); + // 下发配置 + client.push(this.configProtocol.build()); + // 终端状态 + final ClientStatus status = client.status(); + status.setClientId(clientId); + status.setIp(StringUtils.defaultString(client.ip(), this.get(body, Constant.IP))); + status.setSignal(this.get(body, Constant.SIGNAL)); + status.setBattery(this.get(body, Constant.BATTERY)); + status.setCharging(this.get(body, Constant.CHARGING)); + status.setLastHeartbeat(LocalDateTime.now()); + // 上线事件 + this.clientManager.broadcast( + clientId, + this.onlineProtocol.build(status) + ); } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientStatusProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientStatusProtocol.java index f33e2f9..ac9b78c 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientStatusProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientStatusProtocol.java @@ -6,7 +6,7 @@ import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; import com.acgist.taoyao.signal.protocol.Constant; -import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 终端状态信令 @@ -14,7 +14,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; * @author acgist */ @Protocol -public class ClientStatusProtocol extends ProtocolMapAdapter { +public class ClientStatusProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::status"; @@ -23,9 +23,9 @@ public class ClientStatusProtocol extends ProtocolMapAdapter { } @Override - public void execute(String sn, Map body, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { // 如果没有指定终端标识默认查询自己 - message.setBody(this.clientManager.status(this.get(body, Constant.SN, sn))); + message.setBody(this.clientManager.status(this.get(body, Constant.CLIENT_ID, clientId))); client.push(message); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientUnicastProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientUnicastProtocol.java index 691bcbd..eab4a4a 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientUnicastProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/client/ClientUnicastProtocol.java @@ -8,7 +8,7 @@ import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; import com.acgist.taoyao.signal.protocol.Constant; -import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; import lombok.extern.slf4j.Slf4j; @@ -19,7 +19,7 @@ import lombok.extern.slf4j.Slf4j; */ @Slf4j @Protocol -public class ClientUnicastProtocol extends ProtocolMapAdapter { +public class ClientUnicastProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "client::unicast"; @@ -28,7 +28,7 @@ public class ClientUnicastProtocol extends ProtocolMapAdapter { } @Override - public void execute(String sn, Map body, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { final String to = (String) body.remove(Constant.TO); if(StringUtils.isNotEmpty(to)) { this.clientManager.unicast(to, message); diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/AudioActiveSpeakerProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/AudioActiveSpeakerProtocol.java index 023c5fb..6b1b458 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/AudioActiveSpeakerProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/AudioActiveSpeakerProtocol.java @@ -1,13 +1,13 @@ package com.acgist.taoyao.signal.protocol.media; -import java.net.http.WebSocket; import java.util.Map; import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; +import com.acgist.taoyao.signal.media.MediaClient; import com.acgist.taoyao.signal.media.Room; -import com.acgist.taoyao.signal.protocol.ProtocolMediaRoomAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter; /** * 当前讲话终端信令 @@ -15,7 +15,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolMediaRoomAdapter; * @author acgist */ @Protocol -public class AudioActiveSpeakerProtocol extends ProtocolMediaRoomAdapter { +public class AudioActiveSpeakerProtocol extends ProtocolRoomAdapter { public static final String SIGNAL = "audio::active::speaker"; @@ -24,12 +24,12 @@ public class AudioActiveSpeakerProtocol extends ProtocolMediaRoomAdapter { } @Override - public void execute(Room room, Map body, Message message, WebSocket webSocket) { + public void execute(Room room, Map body, MediaClient mediaClient, Message message) { room.broadcast(message); } @Override - public void execute(String sn, Room room, Map body, Client client, Message message) { + public void execute(String clientId, Room room, Map body, Client client, Message message) { // 忽略 } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/DataConsumerStatusProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/ConsumerDataStatusProtocol.java similarity index 55% rename from taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/DataConsumerStatusProtocol.java rename to taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/ConsumerDataStatusProtocol.java index 7cc4834..e4fe40d 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/DataConsumerStatusProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/ConsumerDataStatusProtocol.java @@ -1,5 +1,5 @@ package com.acgist.taoyao.signal.protocol.media; -public class DataConsumerStatusProtocol { +public class ConsumerDataStatusProtocol { } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaListProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaListProtocol.java index 7967def..65561ff 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaListProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaListProtocol.java @@ -8,7 +8,7 @@ import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.property.MediaProperties; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 媒体服务列表信令 @@ -16,7 +16,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; * @author acgist */ @Protocol -public class MediaListProtocol extends ProtocolMapAdapter { +public class MediaListProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "media::list"; @@ -28,7 +28,7 @@ public class MediaListProtocol extends ProtocolMapAdapter { } @Override - public void execute(String sn, Map body, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { message.setBody(this.mediaProperties.getMediaServerList()); client.push(message); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaRebootProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaRebootProtocol.java index 6f23a0d..9d5eb4e 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaRebootProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaRebootProtocol.java @@ -1,12 +1,14 @@ package com.acgist.taoyao.signal.protocol.media; +import java.util.Map; + import org.springframework.beans.factory.annotation.Autowired; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.property.ScriptProperties; +import com.acgist.taoyao.boot.utils.ScriptUtils; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.platform.PlatformScriptEvent; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; import lombok.extern.slf4j.Slf4j; @@ -16,7 +18,7 @@ import lombok.extern.slf4j.Slf4j; * @author acgist */ @Slf4j -public class MediaRebootProtocol extends ProtocolAdapter { +public class MediaRebootProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "media::reboot"; @@ -28,12 +30,10 @@ public class MediaRebootProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { - log.info("重启媒体服务:{}", sn); - // 全员广播 + public void execute(String clientId, Map body, Client client, Message message) { + log.info("重启媒体服务:{}", clientId); this.clientManager.broadcast(message); - // 推送事件 - this.publishEvent(new PlatformScriptEvent(this.scriptProperties.getMediaReboot(), message, client)); + ScriptUtils.execute(this.scriptProperties.getMediaReboot()); } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaRegisterProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaRegisterProtocol.java index 22ac387..25538ed 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaRegisterProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaRegisterProtocol.java @@ -1,12 +1,12 @@ package com.acgist.taoyao.signal.protocol.media; -import java.net.http.WebSocket; import java.util.Map; import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.property.MediaServerProperties; import com.acgist.taoyao.signal.client.Client; +import com.acgist.taoyao.signal.media.MediaClient; import com.acgist.taoyao.signal.protocol.Constant; import com.acgist.taoyao.signal.protocol.ProtocolMediaAdapter; @@ -42,12 +42,12 @@ public class MediaRegisterProtocol extends ProtocolMediaAdapter { } @Override - public void execute(Message message, WebSocket webSocket) { + public void execute(Map body, MediaClient mediaClient, Message message) { log.info("媒体终端注册结果:{}", message); } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaShutdownProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaShutdownProtocol.java index 275d2cf..6ad8014 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaShutdownProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaShutdownProtocol.java @@ -1,5 +1,39 @@ package com.acgist.taoyao.signal.protocol.media; -public class MediaShutdownProtocol { +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.boot.property.ScriptProperties; +import com.acgist.taoyao.boot.utils.ScriptUtils; +import com.acgist.taoyao.signal.client.Client; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; + +import lombok.extern.slf4j.Slf4j; + +/** + * 关闭媒体服务信令 + * + * @author acgist + */ +@Slf4j +public class MediaShutdownProtocol extends ProtocolClientAdapter { + + public static final String SIGNAL = "media::reboot"; + + @Autowired + private ScriptProperties scriptProperties; + + public MediaShutdownProtocol() { + super("关闭媒体服务信令", SIGNAL); + } + + @Override + public void execute(String clientId, Map body, Client client, Message message) { + log.info("关闭媒体服务:{}", clientId); + this.clientManager.broadcast(message); + ScriptUtils.execute(this.scriptProperties.getMediaShutdown()); + } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/NetworkThrottleApplyProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/NetworkThrottleApplyProtocol.java deleted file mode 100644 index 2cd3135..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/NetworkThrottleApplyProtocol.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.acgist.taoyao.signal.protocol.media; - -public class NetworkThrottleApplyProtocol { - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/NetworkThrottleResetProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/NetworkThrottleResetProtocol.java deleted file mode 100644 index ea452bb..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/NetworkThrottleResetProtocol.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.acgist.taoyao.signal.protocol.media; - -public class NetworkThrottleResetProtocol { - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/PeerNewProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/PeerNewProtocol.java deleted file mode 100644 index 2f00b08..0000000 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/PeerNewProtocol.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.acgist.taoyao.signal.protocol.media; - -public class PeerNewProtocol { - -} diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/RouterRtpCapabilitiesProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/RouterRtpCapabilitiesProtocol.java index 8d463ec..0b56631 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/RouterRtpCapabilitiesProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/RouterRtpCapabilitiesProtocol.java @@ -1,13 +1,13 @@ package com.acgist.taoyao.signal.protocol.media; -import java.net.http.WebSocket; import java.util.Map; import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; +import com.acgist.taoyao.signal.media.MediaClient; import com.acgist.taoyao.signal.media.Room; -import com.acgist.taoyao.signal.protocol.ProtocolMediaRoomAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter; /** * 路由RTP能力信令 @@ -15,7 +15,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolMediaRoomAdapter; * @author acgist */ @Protocol -public class RouterRtpCapabilitiesProtocol extends ProtocolMediaRoomAdapter { +public class RouterRtpCapabilitiesProtocol extends ProtocolRoomAdapter { public static final String SIGNAL = "router::rtp::capabilities"; @@ -24,12 +24,12 @@ public class RouterRtpCapabilitiesProtocol extends ProtocolMediaRoomAdapter { } @Override - public void execute(Room room, Map body, Message message, WebSocket webSocket) { + public void execute(Room room, Map body, MediaClient mediaClient, Message message) { // 忽略 } @Override - public void execute(String sn, Room room, Map body, Client client, Message message) { + public void execute(String clientId, Room room, Map body, Client client, Message message) { client.push(room.sendSync(message)); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformErrorProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformErrorProtocol.java index dfb610f..e1db823 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformErrorProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformErrorProtocol.java @@ -1,11 +1,13 @@ package com.acgist.taoyao.signal.protocol.platform; +import java.util.Map; + import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.model.MessageCode; import com.acgist.taoyao.boot.model.MessageCodeException; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 平台异常信令 @@ -13,7 +15,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolAdapter; * @author acgist */ @Protocol -public class PlatformErrorProtocol extends ProtocolAdapter { +public class PlatformErrorProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "platform::error"; @@ -34,7 +36,7 @@ public class PlatformErrorProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { } /** diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformRebootProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformRebootProtocol.java index e323fe4..11b6c08 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformRebootProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/platform/PlatformRebootProtocol.java @@ -1,12 +1,14 @@ package com.acgist.taoyao.signal.protocol.platform; +import java.util.Map; + import org.springframework.beans.factory.annotation.Autowired; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.property.ScriptProperties; +import com.acgist.taoyao.boot.utils.ScriptUtils; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.platform.PlatformScriptEvent; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; import lombok.extern.slf4j.Slf4j; @@ -16,7 +18,7 @@ import lombok.extern.slf4j.Slf4j; * @author acgist */ @Slf4j -public class PlatformRebootProtocol extends ProtocolAdapter { +public class PlatformRebootProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "platform::reboot"; @@ -28,12 +30,10 @@ public class PlatformRebootProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { - log.info("重启平台:{}", sn); - // 全员广播 + public void execute(String clientId, Map body, Client client, Message message) { + log.info("重启平台:{}", clientId); this.clientManager.broadcast(message); - // 推送事件 - this.publishEvent(new PlatformScriptEvent(this.scriptProperties.getPlatformReboot(), message, client)); + ScriptUtils.execute(this.scriptProperties.getPlatformReboot()); } } \ No newline at end of file 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 b18dda3..a4b2980 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 @@ -3,16 +3,20 @@ package com.acgist.taoyao.signal.protocol.platform; import java.util.Map; import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.boot.utils.ScriptUtils; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.platform.PlatformScriptEvent; -import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; +import com.acgist.taoyao.signal.protocol.Constant; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; + +import lombok.extern.slf4j.Slf4j; /** * 执行命令信令 * * @author acgist */ -public class PlatformScriptProtocol extends ProtocolMapAdapter { +@Slf4j +public class PlatformScriptProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "platform::script"; @@ -21,8 +25,16 @@ public class PlatformScriptProtocol extends ProtocolMapAdapter { } @Override - public void execute(String sn, Map body, Client client, Message message) { - this.publishEvent(new PlatformScriptEvent(body, message, client)); + public void execute(String clientId, Map body, Client client, Message message) { + final String script = this.get(body, Constant.SCRIPT); + final String result = ScriptUtils.execute(this.get(body, Constant.SCRIPT)); + log.info(""" + 执行终端:{} + 执行命令:{} + 执行结果:{} + """, clientId, script, result); + message.setBody(Map.of(Constant.RESULT, result)); + client.push(message); } } 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 e84525d..2e52195 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 @@ -1,9 +1,15 @@ package com.acgist.taoyao.signal.protocol.platform; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; + import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.boot.property.ScriptProperties; +import com.acgist.taoyao.boot.utils.ScriptUtils; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.platform.PlatformShutdownEvent; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; import lombok.extern.slf4j.Slf4j; @@ -13,21 +19,33 @@ import lombok.extern.slf4j.Slf4j; * @author acgist */ @Slf4j -public class PlatformShutdownProtocol extends ProtocolAdapter { +public class PlatformShutdownProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "platform::shutdown"; + @Autowired + private ScriptProperties scriptProperties; + public PlatformShutdownProtocol() { super("关闭平台信令", SIGNAL); } @Override - public void execute(String sn, Client client, Message message) { - log.info("关闭平台:{}", sn); - // 全员广播 + public void execute(String clientId, Map body, Client client, Message message) { + log.info("关闭平台:{}", clientId); this.clientManager.broadcast(message); - // 推送事件 - this.publishEvent(new PlatformShutdownEvent(message, client)); + if(this.applicationContext instanceof ConfigurableApplicationContext context) { + // API关闭 + if(context.isActive()) { + // 如果需要完整广播可以设置延时 + context.close(); + } else { + // 其他情况 + } + } else { + // 命令关闭 + ScriptUtils.execute(this.scriptProperties.getPlatformShutdown()); + } } } 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 4e4e382..6a12edc 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 @@ -1,5 +1,36 @@ package com.acgist.taoyao.signal.protocol.room; -public class RoomCloseProtocol { +import java.util.Map; +import com.acgist.taoyao.boot.annotation.Protocol; +import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.signal.client.Client; +import com.acgist.taoyao.signal.media.MediaClient; +import com.acgist.taoyao.signal.media.Room; +import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter; + +/** + * 关闭房间信令 + * + * @author acgist + */ +@Protocol +public class RoomCloseProtocol extends ProtocolRoomAdapter { + + private static final String SIGNAL = "room::close"; + + public RoomCloseProtocol() { + super("关闭房间信令", SIGNAL); + } + + @Override + public void execute(Room room, Map body, MediaClient mediaClient, Message message) { + + } + + @Override + public void execute(String clientId, Room room, Map body, Client client, Message message) { + room.close(); + } + } 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 d4c24c3..a3486b1 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 @@ -4,9 +4,11 @@ import java.util.Map; import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.boot.model.MessageCodeException; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.room.RoomCreateEvent; -import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; +import com.acgist.taoyao.signal.media.Room; +import com.acgist.taoyao.signal.protocol.Constant; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 创建房间信令 @@ -14,7 +16,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; * @author acgist */ @Protocol -public class RoomCreateProtocol extends ProtocolMapAdapter { +public class RoomCreateProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "room::create"; @@ -23,8 +25,22 @@ public class RoomCreateProtocol extends ProtocolMapAdapter { } @Override - public void execute(String sn, Map body, Client client, Message message) { - this.publishEvent(new RoomCreateEvent(body, message, client)); - } + public void execute(String clientId, Map body, Client client, Message message) { + final Long roomId = this.getLong(body, Constant.ROOM_ID); + if (roomId != null && this.roomManager.room(roomId) != null) { + throw MessageCodeException.of("房间已经存在"); + } + // 创建房间 + final Room room = this.roomManager.create( + clientId, + this.get(body, Constant.NAME), + this.get(body, Constant.PASSWORD), + this.get(body, Constant.MEDIA_ID), + message.cloneWidthoutBody() + ); + // 广播消息 + message.setBody(room.getStatus()); + this.clientManager.broadcast(message); + } } 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 6954deb..bf0fdfe 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 @@ -4,9 +4,13 @@ import java.util.Map; import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.boot.model.MessageCode; +import com.acgist.taoyao.boot.model.MessageCodeException; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.room.RoomEnterEvent; -import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; +import com.acgist.taoyao.signal.media.MediaClient; +import com.acgist.taoyao.signal.media.Room; +import com.acgist.taoyao.signal.protocol.Constant; +import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter; /** * 进入房间信令 @@ -14,17 +18,40 @@ import com.acgist.taoyao.signal.protocol.ProtocolMapAdapter; * @author acgist */ @Protocol -public class RoomEnterProtocol extends ProtocolMapAdapter { +public class RoomEnterProtocol extends ProtocolRoomAdapter { public static final String SIGNAL = "room::enter"; public RoomEnterProtocol() { super("进入房间信令", SIGNAL); } + + @Override + public void execute(Room room, Map body, MediaClient mediaClient, Message message) { + } @Override - public void execute(String sn, Map body, Client client, Message message) { - this.publishEvent(new RoomEnterEvent(body, message, client)); + public void execute(String clientId, Room room, Map body, Client client, Message message) { + final String password = this.get(body, Constant.PASSWORD); + final String roomPassowrd = room.getPassword(); + if(roomPassowrd != null && !roomPassowrd.equals(password)) { + throw MessageCodeException.of(MessageCode.CODE_3401, "密码错误"); + } + final MediaClient mediaClient = room.getMediaClient(); + if(client.mediaClient() == null) { + client.mediaClient(mediaClient); + } else if(client.mediaClient() == mediaClient) { + } else { + throw MessageCodeException.of("不在相同媒体服务:" + mediaClient.mediaId()); + } + // 进入房间 + room.enter(client); + // 发送通知 + message.setBody(Map.of( + Constant.ROOM_ID, room.getRoomId(), + Constant.CLIENT_ID, clientId + )); + room.broadcast(message); } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomListProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomListProtocol.java index 574ad32..86d1191 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomListProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomListProtocol.java @@ -1,12 +1,14 @@ package com.acgist.taoyao.signal.protocol.room; +import java.util.Map; + import org.springframework.beans.factory.annotation.Autowired; import com.acgist.taoyao.boot.annotation.Protocol; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.signal.client.Client; import com.acgist.taoyao.signal.media.RoomManager; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; /** * 房间列表信令 @@ -14,7 +16,7 @@ import com.acgist.taoyao.signal.protocol.ProtocolAdapter; * @author acgist */ @Protocol -public class RoomListProtocol extends ProtocolAdapter { +public class RoomListProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "room::list"; @@ -26,7 +28,7 @@ public class RoomListProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { + public void execute(String clientId, Map body, Client client, Message message) { message.setBody(this.roomManager.status()); client.push(message); } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemRebootProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemRebootProtocol.java index 571c28e..06d48b8 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemRebootProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemRebootProtocol.java @@ -1,12 +1,14 @@ package com.acgist.taoyao.signal.protocol.system; +import java.util.Map; + import org.springframework.beans.factory.annotation.Autowired; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.property.ScriptProperties; +import com.acgist.taoyao.boot.utils.ScriptUtils; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.platform.PlatformScriptEvent; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; import lombok.extern.slf4j.Slf4j; @@ -16,7 +18,7 @@ import lombok.extern.slf4j.Slf4j; * @author acgist */ @Slf4j -public class SystemRebootProtocol extends ProtocolAdapter { +public class SystemRebootProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "system::reboot"; @@ -28,10 +30,10 @@ public class SystemRebootProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { - log.info("重启系统:{}", sn); + public void execute(String clientId, Map body, Client client, Message message) { + log.info("重启系统:{}", clientId); this.clientManager.broadcast(message); - this.publishEvent(new PlatformScriptEvent(this.scriptProperties.getSystemReboot(), message, client)); + ScriptUtils.execute(this.scriptProperties.getSystemReboot()); } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemShutdownProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemShutdownProtocol.java index 03e3ac1..69c5174 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemShutdownProtocol.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/system/SystemShutdownProtocol.java @@ -1,12 +1,14 @@ package com.acgist.taoyao.signal.protocol.system; +import java.util.Map; + import org.springframework.beans.factory.annotation.Autowired; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.property.ScriptProperties; +import com.acgist.taoyao.boot.utils.ScriptUtils; import com.acgist.taoyao.signal.client.Client; -import com.acgist.taoyao.signal.event.platform.PlatformScriptEvent; -import com.acgist.taoyao.signal.protocol.ProtocolAdapter; +import com.acgist.taoyao.signal.protocol.ProtocolClientAdapter; import lombok.extern.slf4j.Slf4j; @@ -16,7 +18,7 @@ import lombok.extern.slf4j.Slf4j; * @author acgist */ @Slf4j -public class SystemShutdownProtocol extends ProtocolAdapter { +public class SystemShutdownProtocol extends ProtocolClientAdapter { public static final String SIGNAL = "system::shutdown"; @@ -28,10 +30,10 @@ public class SystemShutdownProtocol extends ProtocolAdapter { } @Override - public void execute(String sn, Client client, Message message) { - log.info("关闭系统:{}", sn); + public void execute(String clientId, Map body, Client client, Message message) { + log.info("关闭系统:{}", clientId); this.clientManager.broadcast(message); - this.publishEvent(new PlatformScriptEvent(this.scriptProperties.getSystemShutdown(), message, client)); + ScriptUtils.execute(this.scriptProperties.getSystemShutdown()); } } diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/service/impl/SecurityServiceImpl.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/service/impl/SecurityServiceImpl.java index 47a4ba1..6a78aeb 100644 --- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/service/impl/SecurityServiceImpl.java +++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/service/impl/SecurityServiceImpl.java @@ -28,14 +28,7 @@ public class SecurityServiceImpl implements SecurityService { @Override public boolean authenticate(Message message, Client client, Protocol protocol) { - if(!client.authorized()) { - return false; - } - // 信令权限鉴定 - if(!protocol.authenticate(message)) { - return false; - } - return true; + return client.authorized() && protocol.authenticate(message); } }