[+] 终端告警信令
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
width="30%"
|
width="30%"
|
||||||
title="终端设置"
|
title="终端设置"
|
||||||
:show-close="false"
|
:show-close="false"
|
||||||
|
v-if="taoyao === null"
|
||||||
v-model="signalVisible"
|
v-model="signalVisible"
|
||||||
>
|
>
|
||||||
<el-form ref="SignalSetting">
|
<el-form ref="SignalSetting">
|
||||||
@@ -81,7 +82,7 @@
|
|||||||
|
|
||||||
<!-- 菜单 -->
|
<!-- 菜单 -->
|
||||||
<div class="menus">
|
<div class="menus">
|
||||||
<el-button type="primary" @click="signalVisible = true">连接信令</el-button>
|
<el-button type="primary" :disabled="taoyao !== null" @click="signalVisible = true">连接信令</el-button>
|
||||||
<el-button type="primary" @click="roomActive = 'enter'; roomVisible = true;">选择房间</el-button>
|
<el-button type="primary" @click="roomActive = 'enter'; roomVisible = true;">选择房间</el-button>
|
||||||
<el-button type="primary" @click="roomActive = 'create';roomVisible = true;">创建房间</el-button>
|
<el-button type="primary" @click="roomActive = 'create';roomVisible = true;">创建房间</el-button>
|
||||||
<el-button>邀请终端</el-button>
|
<el-button>邀请终端</el-button>
|
||||||
@@ -107,8 +108,8 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
room: {},
|
room: {},
|
||||||
rooms: [],
|
rooms: null,
|
||||||
medias: [],
|
medias: null,
|
||||||
config: {
|
config: {
|
||||||
clientId: "taoyao",
|
clientId: "taoyao",
|
||||||
host: "localhost",
|
host: "localhost",
|
||||||
@@ -116,7 +117,7 @@ export default {
|
|||||||
username: "taoyao",
|
username: "taoyao",
|
||||||
password: "taoyao",
|
password: "taoyao",
|
||||||
},
|
},
|
||||||
taoyao: {},
|
taoyao: null,
|
||||||
roomActive: "enter",
|
roomActive: "enter",
|
||||||
roomVisible: false,
|
roomVisible: false,
|
||||||
signalVisible: false,
|
signalVisible: false,
|
||||||
@@ -131,11 +132,13 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async connectSignal() {
|
async connectSignal() {
|
||||||
let self = this;
|
const me = this;
|
||||||
self.taoyao = new Taoyao({ ...this.config });
|
me.taoyao = new Taoyao({ ...this.config });
|
||||||
self.remoteClients = self.taoyao.remoteClients;
|
await me.taoyao.connectSignal(me.callback, me.callbackMedia);
|
||||||
await self.taoyao.connectSignal(self.callback, self.callbackMedia);
|
me.signalVisible = false;
|
||||||
self.signalVisible = false;
|
me.remoteClients = me.taoyao.remoteClients;
|
||||||
|
// 全局绑定
|
||||||
|
window.taoyao = me.taoyao;
|
||||||
},
|
},
|
||||||
async loadList() {
|
async loadList() {
|
||||||
this.rooms = await this.taoyao.roomList();
|
this.rooms = await this.taoyao.roomList();
|
||||||
@@ -208,8 +211,8 @@ export default {
|
|||||||
<style>
|
<style>
|
||||||
.menus{width:100%;top:1rem;left:0;text-align:center;position:fixed;z-index:1;}
|
.menus{width:100%;top:1rem;left:0;text-align:center;position:fixed;z-index:1;}
|
||||||
.clients{width:100%;height:100%;top:0;left:0;position:fixed;}
|
.clients{width:100%;height:100%;top:0;left:0;position:fixed;}
|
||||||
.client{float:left;width:50vw;height:50vh;border:1px solid #eee;}
|
.client{float:left;width:50vw;height:50vh;box-shadow:0 0 1px 0px rgba(0,0,0,0.4);}
|
||||||
.client .buttons{width:100%;bottom:1rem;left:0;text-align:center;position:absolute;padding:0.8rem 0;background: rgba(0,0,0,0.6);text-align:center;}
|
.client .buttons{width:100%;bottom:1rem;left:0;text-align:center;position:absolute;padding:0.8rem 0;background: rgba(0,0,0,0.4);text-align:center;}
|
||||||
.client audio{display:none;}
|
.client audio{display:none;}
|
||||||
.client video{width:100%;height:100%;}
|
.client video{width:100%;height:100%;}
|
||||||
</style>
|
</style>
|
||||||
@@ -12,14 +12,15 @@
|
|||||||
<el-button title="拍照" :icon="Camera" circle />
|
<el-button title="拍照" :icon="Camera" circle />
|
||||||
<el-button title="录像" :icon="VideoCamera" circle />
|
<el-button title="录像" :icon="VideoCamera" circle />
|
||||||
<el-button title="媒体信息" :icon="InfoFilled" circle />
|
<el-button title="媒体信息" :icon="InfoFilled" circle />
|
||||||
<el-select placeholder="视频质量">
|
<el-popover placement="top" :width="200" trigger="hover">
|
||||||
<el-option
|
<template #reference>
|
||||||
v-for="option in options"
|
<el-button>视频质量</el-button>
|
||||||
:key="option.value"
|
</template>
|
||||||
:label="option.label"
|
<el-table :data="options">
|
||||||
:value="option.value"
|
<el-table-column width="100" property="value" label="标识" />
|
||||||
/>
|
<el-table-column width="100" property="label" label="名称" />
|
||||||
</el-select>
|
</el-table>
|
||||||
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* 桃夭
|
* 桃夭
|
||||||
*/
|
*/
|
||||||
import { TaoyaoClient } from "./TaoyaoClient.js";
|
|
||||||
import * as mediasoupClient from "mediasoup-client";
|
import * as mediasoupClient from "mediasoup-client";
|
||||||
import {
|
import {
|
||||||
protocol,
|
protocol,
|
||||||
@@ -30,9 +29,7 @@ const signalChannel = {
|
|||||||
channel: null,
|
channel: null,
|
||||||
// 地址
|
// 地址
|
||||||
address: null,
|
address: null,
|
||||||
// 回调
|
// 请求回调
|
||||||
callback: null,
|
|
||||||
// 回调事件
|
|
||||||
callbackMapping: new Map(),
|
callbackMapping: new Map(),
|
||||||
// 心跳时间
|
// 心跳时间
|
||||||
heartbeatTime: 30 * 1000,
|
heartbeatTime: 30 * 1000,
|
||||||
@@ -156,15 +153,15 @@ const signalChannel = {
|
|||||||
}
|
}
|
||||||
// 前置回调
|
// 前置回调
|
||||||
if (!done) {
|
if (!done) {
|
||||||
await self.preCallback(message);
|
await self.taoyao.preCallback(message);
|
||||||
}
|
}
|
||||||
// 全局回调
|
// 全局回调
|
||||||
if (!done && self.callback) {
|
if (!done && self.callback) {
|
||||||
done = await self.callback(message);
|
done = await self.taoyao.callback(message);
|
||||||
}
|
}
|
||||||
// 后置回调
|
// 后置回调
|
||||||
if (!done) {
|
if (!done) {
|
||||||
await self.postCallback(message);
|
await self.taoyao.postCallback(message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -257,103 +254,6 @@ const signalChannel = {
|
|||||||
clearTimeout(self.heartbeatTimer);
|
clearTimeout(self.heartbeatTimer);
|
||||||
clearTimeout(self.reconnectTimer);
|
clearTimeout(self.reconnectTimer);
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* 前置回调
|
|
||||||
*
|
|
||||||
* @param {*} message
|
|
||||||
*/
|
|
||||||
async preCallback(message) {
|
|
||||||
const self = this;
|
|
||||||
switch (message.header.signal) {
|
|
||||||
case "client::config":
|
|
||||||
self.defaultClientConfig(message);
|
|
||||||
break;
|
|
||||||
case "client::register":
|
|
||||||
console.info("终端注册成功");
|
|
||||||
break;
|
|
||||||
case "media::consume":
|
|
||||||
await self.taoyao.consumeMedia(message);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 后置回调
|
|
||||||
*
|
|
||||||
* @param {*} message 消息
|
|
||||||
*/
|
|
||||||
async postCallback(message) {
|
|
||||||
const self = this;
|
|
||||||
switch (message.header.signal) {
|
|
||||||
case "client::reboot":
|
|
||||||
self.defaultClientReboot(message);
|
|
||||||
break;
|
|
||||||
case "client::shutdown":
|
|
||||||
self.defaultClientShutdown(message);
|
|
||||||
break;
|
|
||||||
case "room::enter":
|
|
||||||
self.defaultRoomEnter(message);
|
|
||||||
break;
|
|
||||||
case "room::client::list":
|
|
||||||
self.defaultRoomClientList(message);
|
|
||||||
break;
|
|
||||||
case "platform::error":
|
|
||||||
self.callbackError(message);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 配置默认回调
|
|
||||||
*
|
|
||||||
* @param {*} message 消息
|
|
||||||
*/
|
|
||||||
defaultClientConfig(message) {
|
|
||||||
const self = this;
|
|
||||||
self.taoyao.audio = { ...defaultAudioConfig, ...message.body.media.audio };
|
|
||||||
self.taoyao.video = { ...defaultVideoConfig, ...message.body.media.video };
|
|
||||||
self.taoyao.webrtc = message.body.webrtc;
|
|
||||||
console.debug(
|
|
||||||
"终端配置",
|
|
||||||
self.taoyao.audio,
|
|
||||||
self.taoyao.video,
|
|
||||||
self.taoyao.webrtc
|
|
||||||
);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 终端重启默认回调
|
|
||||||
*
|
|
||||||
* @param {*} message 消息
|
|
||||||
*/
|
|
||||||
defaultClientReboot(message) {
|
|
||||||
console.info("重启终端");
|
|
||||||
location.reload();
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 终端重启默认回调
|
|
||||||
*
|
|
||||||
* @param {*} message 消息
|
|
||||||
*/
|
|
||||||
defaultClientShutdown(message) {
|
|
||||||
console.info("关闭终端");
|
|
||||||
window.close();
|
|
||||||
},
|
|
||||||
defaultRoomEnter(message) {
|
|
||||||
const { roomId, clientId } = message.body;
|
|
||||||
if(clientId === this.taoyao.clientId) {
|
|
||||||
// 忽略自己
|
|
||||||
} else {
|
|
||||||
this.taoyao.remoteClients.set(clientId, roomId);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
defaultRoomClientList(message) {
|
|
||||||
const self = this;
|
|
||||||
message.body.forEach(v => {
|
|
||||||
if(v.clientId === self.taoyao.clientId) {
|
|
||||||
// 忽略自己
|
|
||||||
} else {
|
|
||||||
self.taoyao.remoteClients.set(v.clientId, self.taoyao.roomId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -479,6 +379,103 @@ class Taoyao {
|
|||||||
callback
|
callback
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 前置回调
|
||||||
|
*
|
||||||
|
* @param {*} message
|
||||||
|
*/
|
||||||
|
async preCallback(message) {
|
||||||
|
const self = this;
|
||||||
|
switch (message.header.signal) {
|
||||||
|
case "client::config":
|
||||||
|
self.defaultClientConfig(message);
|
||||||
|
break;
|
||||||
|
case "client::register":
|
||||||
|
console.info("终端注册成功");
|
||||||
|
break;
|
||||||
|
case "media::consume":
|
||||||
|
await self.consumeMedia(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 后置回调
|
||||||
|
*
|
||||||
|
* @param {*} message 消息
|
||||||
|
*/
|
||||||
|
async postCallback(message) {
|
||||||
|
const self = this;
|
||||||
|
switch (message.header.signal) {
|
||||||
|
case "client::reboot":
|
||||||
|
self.defaultClientReboot(message);
|
||||||
|
break;
|
||||||
|
case "client::shutdown":
|
||||||
|
self.defaultClientShutdown(message);
|
||||||
|
break;
|
||||||
|
case "room::enter":
|
||||||
|
self.defaultRoomEnter(message);
|
||||||
|
break;
|
||||||
|
case "room::client::list":
|
||||||
|
self.defaultRoomClientList(message);
|
||||||
|
break;
|
||||||
|
case "platform::error":
|
||||||
|
self.callbackError(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 配置默认回调
|
||||||
|
*
|
||||||
|
* @param {*} message 消息
|
||||||
|
*/
|
||||||
|
defaultClientConfig(message) {
|
||||||
|
const self = this;
|
||||||
|
self.audio = { ...defaultAudioConfig, ...message.body.media.audio };
|
||||||
|
self.video = { ...defaultVideoConfig, ...message.body.media.video };
|
||||||
|
self.webrtc = message.body.webrtc;
|
||||||
|
console.debug(
|
||||||
|
"终端配置",
|
||||||
|
self.audio,
|
||||||
|
self.video,
|
||||||
|
self.webrtc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 终端重启默认回调
|
||||||
|
*
|
||||||
|
* @param {*} message 消息
|
||||||
|
*/
|
||||||
|
defaultClientReboot(message) {
|
||||||
|
console.info("重启终端");
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 终端重启默认回调
|
||||||
|
*
|
||||||
|
* @param {*} message 消息
|
||||||
|
*/
|
||||||
|
defaultClientShutdown(message) {
|
||||||
|
console.info("关闭终端");
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
defaultRoomEnter(message) {
|
||||||
|
const { roomId, clientId } = message.body;
|
||||||
|
if (clientId === this.clientId) {
|
||||||
|
// 忽略自己
|
||||||
|
} else {
|
||||||
|
this.remoteClients.set(clientId, roomId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defaultRoomClientList(message) {
|
||||||
|
const self = this;
|
||||||
|
message.body.forEach((v) => {
|
||||||
|
if (v.clientId === self.clientId) {
|
||||||
|
// 忽略自己
|
||||||
|
} else {
|
||||||
|
self.remoteClients.set(v.clientId, self.roomId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 错误回调
|
* 错误回调
|
||||||
*/
|
*/
|
||||||
@@ -1091,7 +1088,7 @@ class Taoyao {
|
|||||||
console.log("消费者", consumer);
|
console.log("消费者", consumer);
|
||||||
|
|
||||||
self.callbackMedia("remote", consumer.track, consumer);
|
self.callbackMedia("remote", consumer.track, consumer);
|
||||||
|
|
||||||
// If audio-only mode is enabled, pause it.
|
// If audio-only mode is enabled, pause it.
|
||||||
if (consumer.kind === "video" && !self.videoProduce) {
|
if (consumer.kind === "video" && !self.videoProduce) {
|
||||||
// this.pauseConsumer(consumer);
|
// this.pauseConsumer(consumer);
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* 桃夭终端
|
|
||||||
*/
|
|
||||||
class TaoyaoClient {}
|
|
||||||
|
|
||||||
export { TaoyaoClient };
|
|
||||||
@@ -13,10 +13,3 @@
|
|||||||
|
|
||||||
[信令格式](https://localhost:8888/protocol/list)
|
[信令格式](https://localhost:8888/protocol/list)
|
||||||
|
|
||||||
## 测试脚本
|
|
||||||
|
|
||||||
```
|
|
||||||
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","clientId":"taoyao"}}');
|
|
||||||
socket.send('{"header":{"signal":"client::heartbeat","v":"1.0.0","id":"1"},"body":{}}');
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,5 +1,39 @@
|
|||||||
package com.acgist.taoyao.signal.flute.media;
|
package com.acgist.taoyao.signal.flute.media;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据消费者
|
||||||
|
*
|
||||||
|
* @author acgist
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
public class DataConsumer {
|
public class DataConsumer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消费者终端
|
||||||
|
*/
|
||||||
|
private final ClientWrapper consumeClient;
|
||||||
|
/**
|
||||||
|
* 生产者
|
||||||
|
*/
|
||||||
|
private final Producer producer;
|
||||||
|
/**
|
||||||
|
* 数据流ID
|
||||||
|
*/
|
||||||
|
private final String streamId;
|
||||||
|
/**
|
||||||
|
* 消费者标识
|
||||||
|
*/
|
||||||
|
private final String consumerId;
|
||||||
|
|
||||||
|
public DataConsumer(ClientWrapper consumeClient, Producer producer, String streamId, String consumerId) {
|
||||||
|
this.consumeClient = consumeClient;
|
||||||
|
this.producer = producer;
|
||||||
|
this.streamId = streamId;
|
||||||
|
this.consumerId = consumerId;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,42 @@
|
|||||||
package com.acgist.taoyao.signal.flute.media;
|
package com.acgist.taoyao.signal.flute.media;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据生产者
|
||||||
|
*
|
||||||
|
* @author acgist
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
public class DataProducer {
|
public class DataProducer {
|
||||||
|
|
||||||
private Map<String, DataConsumer> dataConsumers;
|
/**
|
||||||
|
* 生产者终端
|
||||||
|
*/
|
||||||
|
private final ClientWrapper produceClient;
|
||||||
|
/**
|
||||||
|
* 数据流ID
|
||||||
|
*/
|
||||||
|
private final String streamId;
|
||||||
|
/**
|
||||||
|
* 生产者标识
|
||||||
|
*/
|
||||||
|
private final String producerId;
|
||||||
|
/**
|
||||||
|
* 消费者
|
||||||
|
*/
|
||||||
|
private final Map<String, DataConsumer> dataConsumers;
|
||||||
|
|
||||||
|
public DataProducer(ClientWrapper produceClient, String streamId, String producerId) {
|
||||||
|
this.produceClient = produceClient;
|
||||||
|
this.streamId = streamId;
|
||||||
|
this.producerId = producerId;
|
||||||
|
this.dataConsumers = new ConcurrentHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,16 +39,21 @@ public class ClientAlarmProtocol extends ProtocolClientAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(String clientId, ClientType clientType, Client client, Message message, Map<String, Object> body) {
|
public void execute(String clientId, ClientType clientType, Client client, Message message, Map<String, Object> body) {
|
||||||
|
final String alarmMessage = MapUtils.get(body, Constant.MESSAGE);
|
||||||
|
final String alarmDatetime = MapUtils.get(body, Constant.DATETIME);
|
||||||
log.warn(
|
log.warn(
|
||||||
"""
|
"""
|
||||||
终端发生告警:{}
|
终端告警:{}
|
||||||
{}
|
终端类型:{}
|
||||||
{}
|
告警描述:{}
|
||||||
|
告警时间:{}
|
||||||
""",
|
""",
|
||||||
clientId,
|
clientId,
|
||||||
MapUtils.get(body, Constant.MESSAGE),
|
clientType,
|
||||||
MapUtils.get(body, Constant.DATETIME)
|
alarmMessage,
|
||||||
|
alarmDatetime
|
||||||
);
|
);
|
||||||
|
// 业务逻辑
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user