Merge branch 'master' into 重构/1078
# Conflicts: # src/main/java/com/genersoft/iot/vmp/service/bean/InviteErrorCode.java # src/main/resources/application.yml
This commit is contained in:
11
README.md
11
README.md
@@ -16,11 +16,11 @@ WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的开箱即用的网
|
|||||||
前端页面基于vue-admin-template构建 [https://github.com/PanJiaChen/vue-admin-template?tab=readme-ov-file](https://github.com/PanJiaChen/vue-admin-template?tab=readme-ov-file)
|
前端页面基于vue-admin-template构建 [https://github.com/PanJiaChen/vue-admin-template?tab=readme-ov-file](https://github.com/PanJiaChen/vue-admin-template?tab=readme-ov-file)
|
||||||
|
|
||||||
# 应用场景:
|
# 应用场景:
|
||||||
支持浏览器无插件播放摄像头视频。
|
- 支持浏览器无插件播放摄像头视频。
|
||||||
支持国标设备(摄像机、平台、NVR等)设备接入
|
- 支持国标设备(摄像机、平台、NVR等)设备接入
|
||||||
支持rtsp, rtmp,直播设备设备接入,充分利旧。
|
- 支持rtsp, rtmp,直播设备设备接入,充分利旧。
|
||||||
支持国标级联。多平台级联。跨网视频预览。
|
- 支持国标级联。多平台级联。跨网视频预览。
|
||||||
支持跨网网闸平台互联。
|
- 支持跨网网闸平台互联。
|
||||||
|
|
||||||
|
|
||||||
# 文档
|
# 文档
|
||||||
@@ -132,6 +132,7 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
|
|||||||
- [X] 支持ONVIF协议,设备检索,支持点播,云台控制,国标级联点播,自动点播等。
|
- [X] 支持ONVIF协议,设备检索,支持点播,云台控制,国标级联点播,自动点播等。
|
||||||
- [X] 支持部标1078+808协议,支持点播,云台控制,录像回放,位置上报,自动点播等。
|
- [X] 支持部标1078+808协议,支持点播,云台控制,录像回放,位置上报,自动点播等。
|
||||||
- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。
|
- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。
|
||||||
|
- [X] 支持国网B接口协议。支持注册,获取资源,预览等
|
||||||
|
|
||||||
|
|
||||||
# 授权协议
|
# 授权协议
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<groupId>com.genersoft</groupId>
|
<groupId>com.genersoft</groupId>
|
||||||
<artifactId>wvp-pro</artifactId>
|
<artifactId>wvp-pro</artifactId>
|
||||||
<version>2.7.3</version>
|
<version>2.7.4</version>
|
||||||
<name>web video platform</name>
|
<name>web video platform</name>
|
||||||
<description>国标28181视频平台</description>
|
<description>国标28181视频平台</description>
|
||||||
<packaging>${project.packaging}</packaging>
|
<packaging>${project.packaging}</packaging>
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.genersoft.iot.vmp.common;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
|
||||||
|
|
||||||
|
public interface DeviceStatusCallback {
|
||||||
|
public void run(String deviceId, SipTransactionInfo transactionInfo);
|
||||||
|
}
|
||||||
@@ -46,7 +46,6 @@ public class VideoManagerConstants {
|
|||||||
public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_";
|
public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_";
|
||||||
public static final String BROADCAST_WAITE_INVITE = "task_broadcast_waite_invite_";
|
public static final String BROADCAST_WAITE_INVITE = "task_broadcast_waite_invite_";
|
||||||
|
|
||||||
public static final String REGISTER_EXPIRE_TASK_KEY_PREFIX = "VMP_device_register_expire_";
|
|
||||||
public static final String PUSH_STREAM_LIST = "VMP_PUSH_STREAM_LIST_";
|
public static final String PUSH_STREAM_LIST = "VMP_PUSH_STREAM_LIST_";
|
||||||
public static final String WAITE_SEND_PUSH_STREAM = "VMP_WAITE_SEND_PUSH_STREAM:";
|
public static final String WAITE_SEND_PUSH_STREAM = "VMP_WAITE_SEND_PUSH_STREAM:";
|
||||||
public static final String START_SEND_PUSH_STREAM = "VMP_START_SEND_PUSH_STREAM:";
|
public static final String START_SEND_PUSH_STREAM = "VMP_START_SEND_PUSH_STREAM:";
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ public class DeviceQuery {
|
|||||||
if (exist) {
|
if (exist) {
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备编号已存在");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备编号已存在");
|
||||||
}
|
}
|
||||||
deviceService.addDevice(device);
|
deviceService.addCustomDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ public interface DeviceMapper {
|
|||||||
"on_line"+
|
"on_line"+
|
||||||
" FROM wvp_device WHERE on_line = true")
|
" FROM wvp_device WHERE on_line = true")
|
||||||
List<Device> getOnlineDevices();
|
List<Device> getOnlineDevices();
|
||||||
|
|
||||||
@Select("SELECT " +
|
@Select("SELECT " +
|
||||||
"id, " +
|
"id, " +
|
||||||
"device_id, " +
|
"device_id, " +
|
||||||
@@ -414,4 +415,12 @@ public interface DeviceMapper {
|
|||||||
" WHERE id=#{id}"+
|
" WHERE id=#{id}"+
|
||||||
" </script>"})
|
" </script>"})
|
||||||
void updateSubscribeMobilePosition(Device device);
|
void updateSubscribeMobilePosition(Device device);
|
||||||
|
|
||||||
|
@Update(value = {" <script>" +
|
||||||
|
"UPDATE wvp_device " +
|
||||||
|
"SET on_line=false" +
|
||||||
|
" WHERE id in"+
|
||||||
|
"<foreach collection='offlineDevices' item='item' open='(' separator=',' close=')' > #{item.id}</foreach>" +
|
||||||
|
" </script>"})
|
||||||
|
void offlineByList(List<Device> offlineDevices);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ public interface IDeviceService {
|
|||||||
* 添加设备
|
* 添加设备
|
||||||
* @param device
|
* @param device
|
||||||
*/
|
*/
|
||||||
void addDevice(Device device);
|
void addCustomDevice(Device device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面表单更新设备信息
|
* 页面表单更新设备信息
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.gb28181.service.impl;
|
|||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
|
||||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
@@ -15,6 +14,9 @@ import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
|||||||
import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
|
import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
|
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.SipInviteSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.SipInviteSessionManager;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.task.deviceStatus.DeviceStatusTask;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.task.deviceStatus.DeviceStatusTaskInfo;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.task.deviceStatus.DeviceStatusTaskRunner;
|
||||||
import com.genersoft.iot.vmp.gb28181.task.deviceSubscribe.SubscribeTask;
|
import com.genersoft.iot.vmp.gb28181.task.deviceSubscribe.SubscribeTask;
|
||||||
import com.genersoft.iot.vmp.gb28181.task.deviceSubscribe.SubscribeTaskInfo;
|
import com.genersoft.iot.vmp.gb28181.task.deviceSubscribe.SubscribeTaskInfo;
|
||||||
import com.genersoft.iot.vmp.gb28181.task.deviceSubscribe.SubscribeTaskRunner;
|
import com.genersoft.iot.vmp.gb28181.task.deviceSubscribe.SubscribeTaskRunner;
|
||||||
@@ -50,8 +52,7 @@ import javax.sip.SipException;
|
|||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.SynchronousQueue;
|
import java.util.concurrent.SynchronousQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@@ -111,13 +112,83 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SubscribeTaskRunner subscribeTaskRunner;
|
private SubscribeTaskRunner subscribeTaskRunner;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceStatusTaskRunner deviceStatusTaskRunner;
|
||||||
|
|
||||||
private Device getDeviceByDeviceIdFromDb(String deviceId) {
|
private Device getDeviceByDeviceIdFromDb(String deviceId) {
|
||||||
return deviceMapper.getDeviceByDeviceId(deviceId);
|
return deviceMapper.getDeviceByDeviceId(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(String... args) throws Exception {
|
public void run(String... args) throws Exception {
|
||||||
// TODO 处理设备离线
|
|
||||||
|
// 清理数据库不存在但是redis中存在的数据
|
||||||
|
List<Device> devicesInDb = getAll();
|
||||||
|
if (devicesInDb.isEmpty()) {
|
||||||
|
redisCatchStorage.removeAllDevice();
|
||||||
|
}else {
|
||||||
|
List<Device> devicesInRedis = redisCatchStorage.getAllDevices();
|
||||||
|
if (!devicesInRedis.isEmpty()) {
|
||||||
|
Map<String, Device> deviceMapInDb = new HashMap<>();
|
||||||
|
devicesInDb.parallelStream().forEach(device -> {
|
||||||
|
deviceMapInDb.put(device.getDeviceId(), device);
|
||||||
|
});
|
||||||
|
devicesInRedis.parallelStream().forEach(device -> {
|
||||||
|
if (deviceMapInDb.get(device.getDeviceId()) == null
|
||||||
|
&& userSetting.getServerId().equals(device.getServerId())) {
|
||||||
|
redisCatchStorage.removeDevice(device.getDeviceId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置cseq计数
|
||||||
|
redisCatchStorage.resetAllCSEQ();
|
||||||
|
// 处理设备状态
|
||||||
|
List<DeviceStatusTaskInfo> allTaskInfo = deviceStatusTaskRunner.getAllTaskInfo();
|
||||||
|
List<String> onlineDeviceIds = new ArrayList<>();
|
||||||
|
if (!allTaskInfo.isEmpty()) {
|
||||||
|
for (DeviceStatusTaskInfo taskInfo : allTaskInfo) {
|
||||||
|
Device device = getDeviceByDeviceId(taskInfo.getDeviceId());
|
||||||
|
if (device == null) {
|
||||||
|
deviceStatusTaskRunner.removeTask(taskInfo.getDeviceId());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 恢复定时任务, TCP因为连接已经断开必须等待设备重新连接
|
||||||
|
DeviceStatusTask deviceStatusTask = DeviceStatusTask.getInstance(taskInfo.getDeviceId(),
|
||||||
|
taskInfo.getTransactionInfo(), taskInfo.getExpireTime(), this::deviceStatusExpire);
|
||||||
|
deviceStatusTaskRunner.addTask(deviceStatusTask);
|
||||||
|
onlineDeviceIds.add(taskInfo.getDeviceId());
|
||||||
|
}
|
||||||
|
// 除了记录的设备以外, 其他设备全部离线
|
||||||
|
List<Device> onlineDevice = getAllOnlineDevice(userSetting.getServerId());
|
||||||
|
if (!onlineDevice.isEmpty()) {
|
||||||
|
List<Device> offlineDevices = new ArrayList<>();
|
||||||
|
for (Device device : onlineDevice) {
|
||||||
|
if (!onlineDeviceIds.contains(device.getDeviceId())) {
|
||||||
|
// 此设备需要离线
|
||||||
|
device.setOnLine(false);
|
||||||
|
// 清理离线设备的相关缓存
|
||||||
|
cleanOfflineDevice(device);
|
||||||
|
// 更新数据库
|
||||||
|
offlineDevices.add(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!offlineDevices.isEmpty()) {
|
||||||
|
offlineByIds(offlineDevices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
// 所有设备全部离线
|
||||||
|
List<Device> onlineDevice = getAllOnlineDevice(userSetting.getServerId());
|
||||||
|
for (Device device : onlineDevice) {
|
||||||
|
// 此设备需要离线
|
||||||
|
device.setOnLine(false);
|
||||||
|
// 清理离线设备的相关缓存
|
||||||
|
cleanOfflineDevice(device);
|
||||||
|
}
|
||||||
|
offlineByIds(onlineDevice);
|
||||||
|
}
|
||||||
|
|
||||||
// 处理订阅任务
|
// 处理订阅任务
|
||||||
List<SubscribeTaskInfo> taskInfoList = subscribeTaskRunner.getAllTaskInfo();
|
List<SubscribeTaskInfo> taskInfoList = subscribeTaskRunner.getAllTaskInfo();
|
||||||
@@ -127,7 +198,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Device device = getDeviceByDeviceId(taskInfo.getDeviceId());
|
Device device = getDeviceByDeviceId(taskInfo.getDeviceId());
|
||||||
if (device == null || !device.isOnLine()) {
|
if (device == null || !device.isOnLine() || !onlineDeviceIds.contains(taskInfo.getDeviceId())) {
|
||||||
subscribeTaskRunner.removeSubscribe(taskInfo.getKey());
|
subscribeTaskRunner.removeSubscribe(taskInfo.getKey());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -148,6 +219,61 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void offlineByIds(List<Device> offlineDevices) {
|
||||||
|
if (offlineDevices.isEmpty()) {
|
||||||
|
log.info("[更新多个离线设备信息] 参数为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
deviceMapper.offlineByList(offlineDevices);
|
||||||
|
for (Device device : offlineDevices) {
|
||||||
|
device.setOnLine(false);
|
||||||
|
redisCatchStorage.updateDevice(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanOfflineDevice(Device device) {
|
||||||
|
if (subscribeTaskRunner.containsKey(SubscribeTaskForCatalog.getKey(device))) {
|
||||||
|
subscribeTaskRunner.removeSubscribe(SubscribeTaskForCatalog.getKey(device));
|
||||||
|
}
|
||||||
|
if (subscribeTaskRunner.containsKey(SubscribeTaskForMobilPosition.getKey(device))) {
|
||||||
|
subscribeTaskRunner.removeSubscribe(SubscribeTaskForMobilPosition.getKey(device));
|
||||||
|
}
|
||||||
|
//进行通道离线
|
||||||
|
// deviceChannelMapper.offlineByDeviceId(deviceId);
|
||||||
|
// 离线释放所有ssrc
|
||||||
|
List<SsrcTransaction> ssrcTransactions = sessionManager.getSsrcTransactionByDeviceId(device.getDeviceId());
|
||||||
|
if (ssrcTransactions != null && !ssrcTransactions.isEmpty()) {
|
||||||
|
for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
|
||||||
|
mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
|
||||||
|
mediaServerService.closeRTPServer(ssrcTransaction.getMediaServerId(), ssrcTransaction.getStream());
|
||||||
|
sessionManager.removeByCallId(ssrcTransaction.getCallId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 移除订阅
|
||||||
|
removeCatalogSubscribe(device, null);
|
||||||
|
removeMobilePositionSubscribe(device, null);
|
||||||
|
|
||||||
|
List<AudioBroadcastCatch> audioBroadcastCatches = audioBroadcastManager.getByDeviceId(device.getDeviceId());
|
||||||
|
if (!audioBroadcastCatches.isEmpty()) {
|
||||||
|
for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatches) {
|
||||||
|
|
||||||
|
SendRtpInfo sendRtpItem = sendRtpServerService.queryByChannelId(audioBroadcastCatch.getChannelId(), device.getDeviceId());
|
||||||
|
if (sendRtpItem != null) {
|
||||||
|
sendRtpServerService.delete(sendRtpItem);
|
||||||
|
MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
||||||
|
mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
audioBroadcastManager.del(audioBroadcastCatch.getChannelId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deviceStatusExpire(String deviceId, SipTransactionInfo transactionInfo) {
|
||||||
|
log.info("[设备状态] 到期, 编号: {}", deviceId);
|
||||||
|
offline(deviceId, "保活到期");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void online(Device device, SipTransactionInfo sipTransactionInfo) {
|
public void online(Device device, SipTransactionInfo sipTransactionInfo) {
|
||||||
log.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort());
|
log.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort());
|
||||||
@@ -182,6 +308,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
device.setCreateTime(now);
|
device.setCreateTime(now);
|
||||||
device.setUpdateTime(now);
|
device.setUpdateTime(now);
|
||||||
log.info("[设备上线,首次注册]: {},查询设备信息以及通道信息", device.getDeviceId());
|
log.info("[设备上线,首次注册]: {},查询设备信息以及通道信息", device.getDeviceId());
|
||||||
|
addCustomDevice(device);
|
||||||
deviceMapper.add(device);
|
deviceMapper.add(device);
|
||||||
redisCatchStorage.updateDevice(device);
|
redisCatchStorage.updateDevice(device);
|
||||||
try {
|
try {
|
||||||
@@ -193,7 +320,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
sync(device);
|
sync(device);
|
||||||
}else {
|
}else {
|
||||||
device.setServerId(userSetting.getServerId());
|
device.setServerId(userSetting.getServerId());
|
||||||
if(!device.isOnLine()){
|
if(!deviceInDb.isOnLine()){
|
||||||
device.setOnLine(true);
|
device.setOnLine(true);
|
||||||
device.setCreateTime(now);
|
device.setCreateTime(now);
|
||||||
deviceMapper.update(device);
|
deviceMapper.update(device);
|
||||||
@@ -216,6 +343,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
if (device.getSubscribeCycleForMobilePosition() > 0 && !subscribeTaskRunner.containsKey(SubscribeTaskForMobilPosition.getKey(device))) {
|
if (device.getSubscribeCycleForMobilePosition() > 0 && !subscribeTaskRunner.containsKey(SubscribeTaskForMobilPosition.getKey(device))) {
|
||||||
addMobilePositionSubscribe(device, null);
|
addMobilePositionSubscribe(device, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userSetting.getDeviceStatusNotify()) {
|
if (userSetting.getDeviceStatusNotify()) {
|
||||||
// 发送redis消息
|
// 发送redis消息
|
||||||
redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, true);
|
redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, true);
|
||||||
@@ -230,12 +358,19 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
sync(device);
|
sync(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
long expiresTime = Math.min(device.getExpires(), device.getHeartBeatInterval() * device.getHeartBeatCount()) * 1000L;
|
||||||
// 刷新过期任务
|
if (deviceStatusTaskRunner.containsKey(device.getDeviceId())) {
|
||||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
|
if (sipTransactionInfo == null) {
|
||||||
// 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
|
deviceStatusTaskRunner.updateDelay(device.getDeviceId(), System.currentTimeMillis() + expiresTime);
|
||||||
dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "三次心跳超时"),
|
}else {
|
||||||
device.getHeartBeatInterval() * 1000 * device.getHeartBeatCount());
|
deviceStatusTaskRunner.removeTask(device.getDeviceId());
|
||||||
|
DeviceStatusTask task = DeviceStatusTask.getInstance(device.getDeviceId(), sipTransactionInfo, expiresTime, this::deviceStatusExpire);
|
||||||
|
deviceStatusTaskRunner.addTask(task);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
DeviceStatusTask task = DeviceStatusTask.getInstance(device.getDeviceId(), sipTransactionInfo, expiresTime, this::deviceStatusExpire);
|
||||||
|
deviceStatusTaskRunner.addTask(task);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,47 +391,10 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
}
|
}
|
||||||
log.info("[设备离线] {}, device:{}, 心跳间隔: {},心跳超时次数: {}, 上次心跳时间:{}, 上次注册时间: {}", reason, deviceId,
|
log.info("[设备离线] {}, device:{}, 心跳间隔: {},心跳超时次数: {}, 上次心跳时间:{}, 上次注册时间: {}", reason, deviceId,
|
||||||
device.getHeartBeatInterval(), device.getHeartBeatCount(), device.getKeepaliveTime(), device.getRegisterTime());
|
device.getHeartBeatInterval(), device.getHeartBeatCount(), device.getKeepaliveTime(), device.getRegisterTime());
|
||||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + deviceId;
|
|
||||||
dynamicTask.stop(registerExpireTaskKey);
|
|
||||||
if (device.isOnLine()) {
|
|
||||||
if (userSetting.getDeviceStatusNotify()) {
|
|
||||||
// 发送redis消息
|
|
||||||
redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
device.setOnLine(false);
|
device.setOnLine(false);
|
||||||
|
cleanOfflineDevice(device);
|
||||||
redisCatchStorage.updateDevice(device);
|
redisCatchStorage.updateDevice(device);
|
||||||
deviceMapper.update(device);
|
deviceMapper.update(device);
|
||||||
//进行通道离线
|
|
||||||
// deviceChannelMapper.offlineByDeviceId(deviceId);
|
|
||||||
// 离线释放所有ssrc
|
|
||||||
List<SsrcTransaction> ssrcTransactions = sessionManager.getSsrcTransactionByDeviceId(deviceId);
|
|
||||||
if (ssrcTransactions != null && !ssrcTransactions.isEmpty()) {
|
|
||||||
for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
|
|
||||||
mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
|
|
||||||
mediaServerService.closeRTPServer(ssrcTransaction.getMediaServerId(), ssrcTransaction.getStream());
|
|
||||||
sessionManager.removeByCallId(ssrcTransaction.getCallId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 移除订阅
|
|
||||||
removeCatalogSubscribe(device, null);
|
|
||||||
removeMobilePositionSubscribe(device, null);
|
|
||||||
|
|
||||||
List<AudioBroadcastCatch> audioBroadcastCatches = audioBroadcastManager.getByDeviceId(deviceId);
|
|
||||||
if (!audioBroadcastCatches.isEmpty()) {
|
|
||||||
for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatches) {
|
|
||||||
|
|
||||||
SendRtpInfo sendRtpItem = sendRtpServerService.queryByChannelId(audioBroadcastCatch.getChannelId(), deviceId);
|
|
||||||
if (sendRtpItem != null) {
|
|
||||||
sendRtpServerService.delete(sendRtpItem);
|
|
||||||
MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
|
||||||
mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
audioBroadcastManager.del(audioBroadcastCatch.getChannelId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 订阅丢失检查
|
// 订阅丢失检查
|
||||||
@@ -329,7 +427,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
log.info("[目录订阅] 到期, 编号: {}, 设备不存在, 忽略", deviceId);
|
log.info("[目录订阅] 到期, 编号: {}, 设备不存在, 忽略", deviceId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
if (device.isOnLine() && device.getSubscribeCycleForCatalog() > 0) {
|
||||||
addCatalogSubscribe(device, transactionInfo);
|
addCatalogSubscribe(device, transactionInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -341,7 +439,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
log.info("[移动位置订阅] 到期, 编号: {}, 设备不存在, 忽略", deviceId);
|
log.info("[移动位置订阅] 到期, 编号: {}, 设备不存在, 忽略", deviceId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
if (device.isOnLine() && device.getSubscribeCycleForMobilePosition() > 0) {
|
||||||
addMobilePositionSubscribe(device, transactionInfo);
|
addMobilePositionSubscribe(device, transactionInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,9 +479,9 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeCatalogSubscribe(@NotNull Device device, CommonCallback<Boolean> callback) {
|
public boolean removeCatalogSubscribe(@NotNull Device device, CommonCallback<Boolean> callback) {
|
||||||
log.info("[移除目录订阅]: {}", device.getDeviceId());
|
|
||||||
String key = SubscribeTaskForCatalog.getKey(device);
|
String key = SubscribeTaskForCatalog.getKey(device);
|
||||||
if (subscribeTaskRunner.containsKey(key)) {
|
if (subscribeTaskRunner.containsKey(key)) {
|
||||||
|
log.info("[移除目录订阅]: {}", device.getDeviceId());
|
||||||
SipTransactionInfo transactionInfo = subscribeTaskRunner.getTransactionInfo(key);
|
SipTransactionInfo transactionInfo = subscribeTaskRunner.getTransactionInfo(key);
|
||||||
if (transactionInfo == null) {
|
if (transactionInfo == null) {
|
||||||
log.warn("[移除目录订阅] 未找到事务信息,{}", device.getDeviceId());
|
log.warn("[移除目录订阅] 未找到事务信息,{}", device.getDeviceId());
|
||||||
@@ -441,9 +539,10 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeMobilePositionSubscribe(Device device, CommonCallback<Boolean> callback) {
|
public boolean removeMobilePositionSubscribe(Device device, CommonCallback<Boolean> callback) {
|
||||||
log.info("[移除移动位置订阅]: {}", device.getDeviceId());
|
|
||||||
String key = SubscribeTaskForMobilPosition.getKey(device);
|
String key = SubscribeTaskForMobilPosition.getKey(device);
|
||||||
if (subscribeTaskRunner.containsKey(key)) {
|
if (subscribeTaskRunner.containsKey(key)) {
|
||||||
|
log.info("[移除移动位置订阅]: {}", device.getDeviceId());
|
||||||
SipTransactionInfo transactionInfo = subscribeTaskRunner.getTransactionInfo(key);
|
SipTransactionInfo transactionInfo = subscribeTaskRunner.getTransactionInfo(key);
|
||||||
if (transactionInfo == null) {
|
if (transactionInfo == null) {
|
||||||
log.warn("[移除移动位置订阅] 未找到事务信息,{}", device.getDeviceId());
|
log.warn("[移除移动位置订阅] 未找到事务信息,{}", device.getDeviceId());
|
||||||
@@ -580,7 +679,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addDevice(Device device) {
|
public void addCustomDevice(Device device) {
|
||||||
device.setOnLine(false);
|
device.setOnLine(false);
|
||||||
device.setCreateTime(DateUtil.getNow());
|
device.setCreateTime(DateUtil.getNow());
|
||||||
device.setUpdateTime(DateUtil.getNow());
|
device.setUpdateTime(DateUtil.getNow());
|
||||||
@@ -625,9 +724,9 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
if (subscribeTaskRunner.containsKey(SubscribeTaskForMobilPosition.getKey(device))) {
|
if (subscribeTaskRunner.containsKey(SubscribeTaskForMobilPosition.getKey(device))) {
|
||||||
removeMobilePositionSubscribe(device, null);
|
removeMobilePositionSubscribe(device, null);
|
||||||
}
|
}
|
||||||
// 停止状态检测
|
if (deviceStatusTaskRunner.containsKey(deviceId)) {
|
||||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
|
deviceStatusTaskRunner.removeTask(deviceId);
|
||||||
dynamicTask.stop(registerExpireTaskKey);
|
}
|
||||||
platformChannelMapper.delChannelForDeviceId(deviceId);
|
platformChannelMapper.delChannelForDeviceId(deviceId);
|
||||||
deviceChannelMapper.cleanChannelsByDeviceId(device.getId());
|
deviceChannelMapper.cleanChannelsByDeviceId(device.getId());
|
||||||
deviceMapper.del(deviceId);
|
deviceMapper.del(deviceId);
|
||||||
@@ -679,7 +778,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
public void subscribeCatalog(int id, int cycle) {
|
public void subscribeCatalog(int id, int cycle) {
|
||||||
Device device = deviceMapper.query(id);
|
Device device = deviceMapper.query(id);
|
||||||
Assert.notNull(device, "未找到设备");
|
Assert.notNull(device, "未找到设备");
|
||||||
|
Assert.isTrue(device.isOnLine(), "设备已离线");
|
||||||
if (device.getSubscribeCycleForCatalog() == cycle) {
|
if (device.getSubscribeCycleForCatalog() == cycle) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -710,6 +809,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
public void subscribeMobilePosition(int id, int cycle, int interval) {
|
public void subscribeMobilePosition(int id, int cycle, int interval) {
|
||||||
Device device = deviceMapper.query(id);
|
Device device = deviceMapper.query(id);
|
||||||
Assert.notNull(device, "未找到设备");
|
Assert.notNull(device, "未找到设备");
|
||||||
|
Assert.isTrue(device.isOnLine(), "设备已离线");
|
||||||
|
|
||||||
if (device.getSubscribeCycleForMobilePosition() == cycle) {
|
if (device.getSubscribeCycleForMobilePosition() == cycle) {
|
||||||
return;
|
return;
|
||||||
@@ -747,15 +847,16 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
|
|||||||
}
|
}
|
||||||
if (!Objects.equals(deviceInDb.getHeartBeatCount(), device.getHeartBeatCount())
|
if (!Objects.equals(deviceInDb.getHeartBeatCount(), device.getHeartBeatCount())
|
||||||
|| !Objects.equals(deviceInDb.getHeartBeatInterval(), device.getHeartBeatInterval())) {
|
|| !Objects.equals(deviceInDb.getHeartBeatInterval(), device.getHeartBeatInterval())) {
|
||||||
// 刷新过期任务
|
|
||||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
|
|
||||||
// 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
|
|
||||||
dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "三次心跳超时"),
|
|
||||||
device.getHeartBeatInterval() * 1000 * device.getHeartBeatCount());
|
|
||||||
deviceInDb.setHeartBeatCount(device.getHeartBeatCount());
|
deviceInDb.setHeartBeatCount(device.getHeartBeatCount());
|
||||||
deviceInDb.setHeartBeatInterval(device.getHeartBeatInterval());
|
deviceInDb.setHeartBeatInterval(device.getHeartBeatInterval());
|
||||||
deviceInDb.setPositionCapability(device.getPositionCapability());
|
deviceInDb.setPositionCapability(device.getPositionCapability());
|
||||||
updateDevice(deviceInDb);
|
updateDevice(deviceInDb);
|
||||||
|
|
||||||
|
long expiresTime = Math.min(device.getExpires(), device.getHeartBeatInterval() * device.getHeartBeatCount()) * 1000L;
|
||||||
|
if (deviceStatusTaskRunner.containsKey(device.getDeviceId())) {
|
||||||
|
deviceStatusTaskRunner.updateDelay(device.getDeviceId(), expiresTime + System.currentTimeMillis());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,35 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(String... args) throws Exception {
|
public void run(String... args) throws Exception {
|
||||||
|
|
||||||
|
// 查找国标推流
|
||||||
|
List<SendRtpInfo> sendRtpItems = redisCatchStorage.queryAllSendRTPServer();
|
||||||
|
if (!sendRtpItems.isEmpty()) {
|
||||||
|
for (SendRtpInfo sendRtpItem : sendRtpItems) {
|
||||||
|
MediaServer mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
||||||
|
CommonGBChannel channel = channelService.getOne(sendRtpItem.getChannelId());
|
||||||
|
if (channel == null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sendRtpServerService.delete(sendRtpItem);
|
||||||
|
if (mediaServerItem != null) {
|
||||||
|
ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc());
|
||||||
|
boolean stopResult = mediaServerService.initStopSendRtp(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc());
|
||||||
|
if (stopResult) {
|
||||||
|
Platform platform = queryPlatformByServerGBId(sendRtpItem.getTargetId());
|
||||||
|
|
||||||
|
if (platform != null) {
|
||||||
|
try {
|
||||||
|
commanderForPlatform.streamByeCmd(platform, sendRtpItem, channel);
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
log.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 启动时 如果存在未过期的注册平台,则发送注销
|
// 启动时 如果存在未过期的注册平台,则发送注销
|
||||||
List<PlatformRegisterTaskInfo> registerTaskInfoList = statusTaskRunner.getAllRegisterTaskInfo();
|
List<PlatformRegisterTaskInfo> registerTaskInfoList = statusTaskRunner.getAllRegisterTaskInfo();
|
||||||
if (registerTaskInfoList.isEmpty()) {
|
if (registerTaskInfoList.isEmpty()) {
|
||||||
@@ -415,7 +444,6 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void keepaliveExpire(String platformServerId, int failCount) {
|
private void keepaliveExpire(String platformServerId, int failCount) {
|
||||||
log.info("[国标级联] 心跳到期, 上级平台编号: {}", platformServerId);
|
|
||||||
Platform platform = queryPlatformByServerGBId(platformServerId);
|
Platform platform = queryPlatformByServerGBId(platformServerId);
|
||||||
if (platform == null || !platform.isEnable()) {
|
if (platform == null || !platform.isEnable()) {
|
||||||
log.info("[国标级联] 心跳到期, 上级平台编号: {}, 平台不存在或者未启用, 忽略", platformServerId);
|
log.info("[国标级联] 心跳到期, 上级平台编号: {}, 平台不存在或者未启用, 忽略", platformServerId);
|
||||||
|
|||||||
@@ -510,6 +510,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
try {
|
try {
|
||||||
sendRtpInfo = sendRtpServerService.createSendRtpInfo(mediaServerItem, null, null, playSsrc, device.getDeviceId(), "talk", stream,
|
sendRtpInfo = sendRtpServerService.createSendRtpInfo(mediaServerItem, null, null, playSsrc, device.getDeviceId(), "talk", stream,
|
||||||
channel.getId(), true, false);
|
channel.getId(), true, false);
|
||||||
|
sendRtpInfo.setPlayType(InviteStreamType.TALK);
|
||||||
}catch (PlayException e) {
|
}catch (PlayException e) {
|
||||||
log.info("[语音对讲]开始 获取发流端口失败 deviceId: {}, channelId: {},", device.getDeviceId(), channel.getDeviceId());
|
log.info("[语音对讲]开始 获取发流端口失败 deviceId: {}, channelId: {},", device.getDeviceId(), channel.getDeviceId());
|
||||||
return;
|
return;
|
||||||
@@ -582,7 +583,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
sendRtpInfo.setCallId(response.getCallIdHeader().getCallId());
|
sendRtpInfo.setCallId(response.getCallIdHeader().getCallId());
|
||||||
sendRtpServerService.update(sendRtpInfo);
|
sendRtpServerService.update(sendRtpInfo);
|
||||||
|
|
||||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), sendRtpInfo.getChannelId(), "talk", sendRtpInfo.getApp(),
|
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), sendRtpInfo.getChannelId(), response.getCallIdHeader().getCallId(), sendRtpInfo.getApp(),
|
||||||
sendRtpInfo.getStream(), sendRtpInfo.getSsrc(), sendRtpInfo.getMediaServerId(),
|
sendRtpInfo.getStream(), sendRtpInfo.getSsrc(), sendRtpInfo.getMediaServerId(),
|
||||||
response, InviteSessionType.TALK);
|
response, InviteSessionType.TALK);
|
||||||
|
|
||||||
@@ -654,11 +655,11 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
// 主动连接失败,结束流程, 清理数据
|
// 主动连接失败,结束流程, 清理数据
|
||||||
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
||||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||||
callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
callback.run(InviteErrorCode.ERROR_FOR_TCP_ACTIVE_CONNECTION_REFUSED_ERROR.getCode(),
|
||||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
InviteErrorCode.ERROR_FOR_TCP_ACTIVE_CONNECTION_REFUSED_ERROR.getMsg(), null);
|
||||||
inviteStreamService.call(InviteSessionType.BROADCAST, channel.getId(), null,
|
inviteStreamService.call(InviteSessionType.BROADCAST, channel.getId(), null,
|
||||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
InviteErrorCode.ERROR_FOR_TCP_ACTIVE_CONNECTION_REFUSED_ERROR.getCode(),
|
||||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
InviteErrorCode.ERROR_FOR_TCP_ACTIVE_CONNECTION_REFUSED_ERROR.getMsg(), null);
|
||||||
}
|
}
|
||||||
} catch (SdpException e) {
|
} catch (SdpException e) {
|
||||||
log.error("[TCP主动连接对方] deviceId: {}, channelId: {}, 解析200OK的SDP信息失败", device.getDeviceId(), channel.getDeviceId(), e);
|
log.error("[TCP主动连接对方] deviceId: {}, channelId: {}, 解析200OK的SDP信息失败", device.getDeviceId(), channel.getDeviceId(), e);
|
||||||
@@ -724,7 +725,6 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
inviteInfo.setStreamInfo(streamInfo);
|
inviteInfo.setStreamInfo(streamInfo);
|
||||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return streamInfo;
|
return streamInfo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.task;
|
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpInfo;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelService;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IPlatformService;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
|
||||||
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
|
||||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
|
||||||
import com.genersoft.iot.vmp.service.ISendRtpServerService;
|
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.CommandLineRunner;
|
|
||||||
import org.springframework.core.annotation.Order;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.sip.InvalidArgumentException;
|
|
||||||
import javax.sip.SipException;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统启动时控制设备
|
|
||||||
* @author lin
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
@Order(value=14)
|
|
||||||
public class SipRunner implements CommandLineRunner {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SSRCFactory ssrcFactory;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IDeviceService deviceService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IMediaServerService mediaServerService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IPlatformService platformService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IGbChannelService channelService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ISIPCommanderForPlatform commanderForPlatform;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ISendRtpServerService sendRtpServerService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserSetting userSetting;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(String... args) throws Exception {
|
|
||||||
List<Device> deviceList = deviceService.getAllOnlineDevice(userSetting.getServerId());
|
|
||||||
|
|
||||||
for (Device device : deviceList) {
|
|
||||||
if (deviceService.expire(device)){
|
|
||||||
deviceService.offline(device.getDeviceId(), "注册已过期");
|
|
||||||
}else {
|
|
||||||
deviceService.online(device, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 重置cseq计数
|
|
||||||
redisCatchStorage.resetAllCSEQ();
|
|
||||||
// 清理redis
|
|
||||||
// 清理数据库不存在但是redis中存在的数据
|
|
||||||
List<Device> devicesInDb = deviceService.getAll();
|
|
||||||
if (devicesInDb.isEmpty()) {
|
|
||||||
redisCatchStorage.removeAllDevice();
|
|
||||||
}else {
|
|
||||||
List<Device> devicesInRedis = redisCatchStorage.getAllDevices();
|
|
||||||
if (!devicesInRedis.isEmpty()) {
|
|
||||||
Map<String, Device> deviceMapInDb = new HashMap<>();
|
|
||||||
devicesInDb.parallelStream().forEach(device -> {
|
|
||||||
deviceMapInDb.put(device.getDeviceId(), device);
|
|
||||||
});
|
|
||||||
devicesInRedis.parallelStream().forEach(device -> {
|
|
||||||
if (deviceMapInDb.get(device.getDeviceId()) == null
|
|
||||||
&& userSetting.getServerId().equals(device.getServerId())) {
|
|
||||||
redisCatchStorage.removeDevice(device.getDeviceId());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 查找国标推流
|
|
||||||
List<SendRtpInfo> sendRtpItems = redisCatchStorage.queryAllSendRTPServer();
|
|
||||||
if (!sendRtpItems.isEmpty()) {
|
|
||||||
for (SendRtpInfo sendRtpItem : sendRtpItems) {
|
|
||||||
MediaServer mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
|
||||||
CommonGBChannel channel = channelService.getOne(sendRtpItem.getChannelId());
|
|
||||||
if (channel == null){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sendRtpServerService.delete(sendRtpItem);
|
|
||||||
if (mediaServerItem != null) {
|
|
||||||
ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc());
|
|
||||||
boolean stopResult = mediaServerService.initStopSendRtp(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc());
|
|
||||||
if (stopResult) {
|
|
||||||
Platform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getTargetId());
|
|
||||||
|
|
||||||
if (platform != null) {
|
|
||||||
try {
|
|
||||||
commanderForPlatform.streamByeCmd(platform, sendRtpItem, channel);
|
|
||||||
} catch (InvalidArgumentException | ParseException | SipException e) {
|
|
||||||
log.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.task.deviceStatus;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.common.DeviceStatusCallback;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.Delayed;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Data
|
||||||
|
public class DeviceStatusTask implements Delayed {
|
||||||
|
|
||||||
|
private String deviceId;
|
||||||
|
|
||||||
|
private SipTransactionInfo transactionInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 超时时间(单位: 毫秒)
|
||||||
|
*/
|
||||||
|
private long delayTime;
|
||||||
|
|
||||||
|
private DeviceStatusCallback callback;
|
||||||
|
|
||||||
|
public static DeviceStatusTask getInstance(String deviceId, SipTransactionInfo transactionInfo, long delayTime, DeviceStatusCallback callback) {
|
||||||
|
DeviceStatusTask deviceStatusTask = new DeviceStatusTask();
|
||||||
|
deviceStatusTask.setDeviceId(deviceId);
|
||||||
|
deviceStatusTask.setTransactionInfo(transactionInfo);
|
||||||
|
deviceStatusTask.setDelayTime((delayTime * 1000L - 500L) + System.currentTimeMillis());
|
||||||
|
deviceStatusTask.setCallback(callback);
|
||||||
|
return deviceStatusTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expired() {
|
||||||
|
if (callback == null) {
|
||||||
|
log.info("[设备离线] 未找到过期处理回调, {}", deviceId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback.run(deviceId, transactionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDelay(@NotNull TimeUnit unit) {
|
||||||
|
return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(@NotNull Delayed o) {
|
||||||
|
return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceStatusTaskInfo getInfo(){
|
||||||
|
DeviceStatusTaskInfo taskInfo = new DeviceStatusTaskInfo();
|
||||||
|
taskInfo.setTransactionInfo(transactionInfo);
|
||||||
|
taskInfo.setDeviceId(deviceId);
|
||||||
|
return taskInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.task.deviceStatus;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DeviceStatusTaskInfo{
|
||||||
|
|
||||||
|
private String deviceId;
|
||||||
|
|
||||||
|
private SipTransactionInfo transactionInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过期时间
|
||||||
|
*/
|
||||||
|
private long expireTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.task.deviceStatus;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
|
||||||
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.DelayQueue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class DeviceStatusTaskRunner {
|
||||||
|
|
||||||
|
private final Map<String, DeviceStatusTask> subscribes = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private final DelayQueue<DeviceStatusTask> delayQueue = new DelayQueue<>();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<Object, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserSetting userSetting;
|
||||||
|
|
||||||
|
private final String prefix = "VMP_DEVICE_STATUS";
|
||||||
|
|
||||||
|
// 状态过期检查
|
||||||
|
@Scheduled(fixedDelay = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
public void expirationCheck(){
|
||||||
|
while (!delayQueue.isEmpty()) {
|
||||||
|
DeviceStatusTask take = null;
|
||||||
|
try {
|
||||||
|
take = delayQueue.take();
|
||||||
|
try {
|
||||||
|
removeTask(take.getDeviceId());
|
||||||
|
take.expired();
|
||||||
|
}catch (Exception e) {
|
||||||
|
log.error("[设备状态到期] 到期处理时出现异常, 设备编号: {} ", take.getDeviceId());
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error("[设备状态任务] ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTask(DeviceStatusTask task) {
|
||||||
|
Duration duration = Duration.ofSeconds((task.getDelayTime() - System.currentTimeMillis())/1000);
|
||||||
|
if (duration.getSeconds() < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subscribes.put(task.getDeviceId(), task);
|
||||||
|
String key = String.format("%s_%s_%s", prefix, userSetting.getServerId(), task.getDeviceId());
|
||||||
|
redisTemplate.opsForValue().set(key, task.getInfo(), duration);
|
||||||
|
delayQueue.offer(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeTask(String key) {
|
||||||
|
DeviceStatusTask task = subscribes.get(key);
|
||||||
|
if (task == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String redisKey = String.format("%s_%s_%s", prefix, userSetting.getServerId(), task.getDeviceId());
|
||||||
|
redisTemplate.delete(redisKey);
|
||||||
|
subscribes.remove(key);
|
||||||
|
if (delayQueue.contains(task)) {
|
||||||
|
boolean remove = delayQueue.remove(task);
|
||||||
|
if (!remove) {
|
||||||
|
log.info("[移除状态任务] 从延时队列内移除失败: {}", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SipTransactionInfo getTransactionInfo(String key) {
|
||||||
|
DeviceStatusTask task = subscribes.get(key);
|
||||||
|
if (task == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return task.getTransactionInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updateDelay(String key, long expirationTime) {
|
||||||
|
DeviceStatusTask task = subscribes.get(key);
|
||||||
|
if (task == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log.info("[更新状态任务时间] 编号: {}", key);
|
||||||
|
if (delayQueue.contains(task)) {
|
||||||
|
boolean remove = delayQueue.remove(task);
|
||||||
|
if (!remove) {
|
||||||
|
log.info("[更新状态任务时间] 从延时队列内移除失败: {}", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
task.setDelayTime(expirationTime);
|
||||||
|
delayQueue.offer(task);
|
||||||
|
String redisKey = String.format("%s_%s_%s", prefix, userSetting.getServerId(), task.getDeviceId());
|
||||||
|
Duration duration = Duration.ofSeconds((expirationTime - System.currentTimeMillis())/1000);
|
||||||
|
redisTemplate.expire(redisKey, duration);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(String key) {
|
||||||
|
return subscribes.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DeviceStatusTaskInfo> getAllTaskInfo(){
|
||||||
|
String scanKey = String.format("%s_%s_*", prefix, userSetting.getServerId());
|
||||||
|
List<Object> values = RedisUtil.scan(redisTemplate, scanKey);
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<DeviceStatusTaskInfo> result = new ArrayList<>();
|
||||||
|
for (Object value : values) {
|
||||||
|
String redisKey = (String)value;
|
||||||
|
DeviceStatusTaskInfo taskInfo = (DeviceStatusTaskInfo)redisTemplate.opsForValue().get(redisKey);
|
||||||
|
if (taskInfo == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Long expire = redisTemplate.getExpire(redisKey);
|
||||||
|
taskInfo.setExpireTime(expire);
|
||||||
|
result.add(taskInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -164,7 +164,8 @@ public class SIPRequestHeaderProvider {
|
|||||||
// SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
|
// SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(device.getDeviceId(), device.getHostAddress());
|
||||||
// via
|
// via
|
||||||
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
||||||
ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), transactionInfo.getViaBranch());
|
// ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), transactionInfo.getViaBranch());
|
||||||
|
ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), SipUtils.getNewViaTag());
|
||||||
// viaHeader.setRPort();
|
// viaHeader.setRPort();
|
||||||
viaHeaders.add(viaHeader);
|
viaHeaders.add(viaHeader);
|
||||||
//from
|
//from
|
||||||
|
|||||||
@@ -136,16 +136,17 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String keepalive(Platform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException {
|
public String keepalive(Platform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException {
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
log.info("[国标级联] 发送心跳, 上级平台编号: {}", parentPlatform.getServerGBId());
|
||||||
StringBuffer keepaliveXml = new StringBuffer(200);
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
keepaliveXml.append("<?xml version=\"1.0\" encoding=\"")
|
StringBuffer keepaliveXml = new StringBuffer(200);
|
||||||
.append(characterSet).append("\"?>\r\n")
|
keepaliveXml.append("<?xml version=\"1.0\" encoding=\"")
|
||||||
.append("<Notify>\r\n")
|
.append(characterSet).append("\"?>\r\n")
|
||||||
.append("<CmdType>Keepalive</CmdType>\r\n")
|
.append("<Notify>\r\n")
|
||||||
.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n")
|
.append("<CmdType>Keepalive</CmdType>\r\n")
|
||||||
.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n")
|
.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n")
|
||||||
.append("<Status>OK</Status>\r\n")
|
.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n")
|
||||||
.append("</Notify>\r\n");
|
.append("<Status>OK</Status>\r\n")
|
||||||
|
.append("</Notify>\r\n");
|
||||||
|
|
||||||
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
||||||
|
|
||||||
|
|||||||
@@ -113,8 +113,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
|||||||
device.setTransport("TCP".equalsIgnoreCase(transport) ? "TCP" : "UDP");
|
device.setTransport("TCP".equalsIgnoreCase(transport) ? "TCP" : "UDP");
|
||||||
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), registerOkResponse);
|
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), registerOkResponse);
|
||||||
device.setRegisterTime(DateUtil.getNow());
|
device.setRegisterTime(DateUtil.getNow());
|
||||||
SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse) registerOkResponse);
|
deviceService.online(device, null);
|
||||||
deviceService.online(device, sipTransactionInfo);
|
|
||||||
} else {
|
} else {
|
||||||
deviceService.offline(deviceId, "主动注销");
|
deviceService.offline(deviceId, "主动注销");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String cmd = XmlUtil.getText(rootElement, "CmdType");
|
String cmd = XmlUtil.getText(rootElement, "CmdType");
|
||||||
|
log.info("[收到订阅请求] 类型: {}", cmd);
|
||||||
if (CmdType.MOBILE_POSITION.equals(cmd)) {
|
if (CmdType.MOBILE_POSITION.equals(cmd)) {
|
||||||
processNotifyMobilePosition(request, rootElement);
|
processNotifyMobilePosition(request, rootElement);
|
||||||
// } else if (CmdType.ALARM.equals(cmd)) {
|
// } else if (CmdType.ALARM.equals(cmd)) {
|
||||||
@@ -157,12 +158,14 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
|
|||||||
|
|
||||||
private void processNotifyCatalogList(SIPRequest request, Element rootElement) throws SipException {
|
private void processNotifyCatalogList(SIPRequest request, Element rootElement) throws SipException {
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
|
log.info("[处理目录订阅] 发现request为NUll。已忽略");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String platformId = SipUtils.getUserIdFromFromHeader(request);
|
String platformId = SipUtils.getUserIdFromFromHeader(request);
|
||||||
String deviceId = XmlUtil.getText(rootElement, "DeviceID");
|
String deviceId = XmlUtil.getText(rootElement, "DeviceID");
|
||||||
Platform platform = platformService.queryPlatformByServerGBId(platformId);
|
Platform platform = platformService.queryPlatformByServerGBId(platformId);
|
||||||
if (platform == null){
|
if (platform == null){
|
||||||
|
log.info("[处理目录订阅] 未找到平台 {}。已忽略", platformId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,12 +189,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
|
|||||||
SubscribeInfo subscribeInfo = SubscribeInfo.getInstance(response, platformId, expires,
|
SubscribeInfo subscribeInfo = SubscribeInfo.getInstance(response, platformId, expires,
|
||||||
(EventHeader)request.getHeader(EventHeader.NAME));
|
(EventHeader)request.getHeader(EventHeader.NAME));
|
||||||
|
|
||||||
if (subscribeInfo.getExpires() > 0) {
|
|
||||||
subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo);
|
|
||||||
}else if (subscribeInfo.getExpires() == 0) {
|
|
||||||
subscribeHolder.removeCatalogSubscribe(platformId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subscribeInfo.getExpires() == 0) {
|
if (subscribeInfo.getExpires() == 0) {
|
||||||
subscribeHolder.removeCatalogSubscribe(platformId);
|
subscribeHolder.removeCatalogSubscribe(platformId);
|
||||||
}else {
|
}else {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
|
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
import com.genersoft.iot.vmp.common.RemoteAddressInfo;
|
||||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
||||||
import com.genersoft.iot.vmp.common.RemoteAddressInfo;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SipMsgInfo;
|
import com.genersoft.iot.vmp.gb28181.bean.SipMsgInfo;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.task.deviceStatus.DeviceStatusTaskRunner;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
|
||||||
@@ -48,6 +48,9 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IDeviceService deviceService;
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceStatusTaskRunner statusTaskRunner;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserSetting userSetting;
|
private UserSetting userSetting;
|
||||||
|
|
||||||
@@ -111,20 +114,16 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
|
|||||||
|
|
||||||
if (device.isOnLine()) {
|
if (device.isOnLine()) {
|
||||||
deviceService.updateDevice(device);
|
deviceService.updateDevice(device);
|
||||||
|
long expiresTime = Math.min(device.getExpires(), device.getHeartBeatInterval() * device.getHeartBeatCount()) * 1000L;
|
||||||
|
if (statusTaskRunner.containsKey(device.getDeviceId())) {
|
||||||
|
statusTaskRunner.updateDelay(device.getDeviceId(), expiresTime + System.currentTimeMillis());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (userSetting.getGbDeviceOnline() == 1) {
|
if (userSetting.getGbDeviceOnline() == 1) {
|
||||||
// 对于已经离线的设备判断他的注册是否已经过期
|
// 对于已经离线的设备判断他的注册是否已经过期
|
||||||
device.setOnLine(true);
|
|
||||||
device.setRegisterTime(DateUtil.getNow());
|
|
||||||
deviceService.online(device, null);
|
deviceService.online(device, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 刷新过期任务
|
|
||||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
|
|
||||||
// 如果三次心跳失败,则设置设备离线
|
|
||||||
dynamicTask.startDelay(registerExpireTaskKey, () -> deviceService.offline(device.getDeviceId(), "三次心跳超时"),
|
|
||||||
device.getHeartBeatInterval() * 1000 * device.getHeartBeatCount());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.springframework.stereotype.Component;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -442,8 +443,10 @@ public class ZLMRESTfulUtils {
|
|||||||
param.put("vhost", "__defaultVhost__");
|
param.put("vhost", "__defaultVhost__");
|
||||||
param.put("app", app);
|
param.put("app", app);
|
||||||
param.put("stream", stream);
|
param.put("stream", stream);
|
||||||
param.put("stamp", stamp);
|
BigDecimal bigDecimal = new BigDecimal(stamp);
|
||||||
|
param.put("stamp", bigDecimal);
|
||||||
param.put("schema", schema);
|
param.put("schema", schema);
|
||||||
|
System.out.println(bigDecimal);
|
||||||
return sendPost(mediaServer, "seekRecordStamp",param, null);
|
return sendPost(mediaServer, "seekRecordStamp",param, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ public enum InviteErrorCode {
|
|||||||
ERROR_FOR_SIP_SENDING_FAILED(-10, "命令发送失败"),
|
ERROR_FOR_SIP_SENDING_FAILED(-10, "命令发送失败"),
|
||||||
ERROR_FOR_ASSIST_NOT_READY(-11, "没有可用的assist服务"),
|
ERROR_FOR_ASSIST_NOT_READY(-11, "没有可用的assist服务"),
|
||||||
ERROR_FOR_PARAMETER_ERROR(-13, "参数异常"),
|
ERROR_FOR_PARAMETER_ERROR(-13, "参数异常"),
|
||||||
ERROR_FOR_FINISH(-14, "已结束"),
|
ERROR_FOR_TCP_ACTIVE_CONNECTION_REFUSED_ERROR(-14, "TCP主动连接失败"),
|
||||||
|
ERROR_FOR_FINISH(-20, "已结束"),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final int code;
|
private final int code;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// sidebar
|
// sidebar
|
||||||
$menuText:#bfcbd9;
|
$menuText:#bfcbd9;
|
||||||
$menuActiveText:#409EFF;
|
$menuActiveText:#409EFF;
|
||||||
$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
|
$subMenuActiveText: #f4f4f5; //https://github.com/ElemeFE/element/issues/12951
|
||||||
|
|
||||||
$menuBg:#304156;
|
$menuBg: #304156;
|
||||||
$menuHover:#263445;
|
$menuHover:#263445;
|
||||||
|
|
||||||
$subMenuBg:#1f2d3d;
|
$subMenuBg:#1f2d3d;
|
||||||
|
|||||||
466
数据库/2.7.4/初始化-mysql-2.7.4.sql
Normal file
466
数据库/2.7.4/初始化-mysql-2.7.4.sql
Normal file
@@ -0,0 +1,466 @@
|
|||||||
|
/*建表*/
|
||||||
|
drop table IF EXISTS wvp_device;
|
||||||
|
create table IF NOT EXISTS wvp_device
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id character varying(50) not null,
|
||||||
|
name character varying(255),
|
||||||
|
manufacturer character varying(255),
|
||||||
|
model character varying(255),
|
||||||
|
firmware character varying(255),
|
||||||
|
transport character varying(50),
|
||||||
|
stream_mode character varying(50),
|
||||||
|
on_line bool default false,
|
||||||
|
register_time character varying(50),
|
||||||
|
keepalive_time character varying(50),
|
||||||
|
ip character varying(50),
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
port integer,
|
||||||
|
expires integer,
|
||||||
|
subscribe_cycle_for_catalog integer DEFAULT 0,
|
||||||
|
subscribe_cycle_for_mobile_position integer DEFAULT 0,
|
||||||
|
mobile_position_submission_interval integer DEFAULT 5,
|
||||||
|
subscribe_cycle_for_alarm integer DEFAULT 0,
|
||||||
|
host_address character varying(50),
|
||||||
|
charset character varying(50),
|
||||||
|
ssrc_check bool default false,
|
||||||
|
geo_coord_sys character varying(50),
|
||||||
|
media_server_id character varying(50) default 'auto',
|
||||||
|
custom_name character varying(255),
|
||||||
|
sdp_ip character varying(50),
|
||||||
|
local_ip character varying(50),
|
||||||
|
password character varying(255),
|
||||||
|
as_message_channel bool default false,
|
||||||
|
heart_beat_interval integer,
|
||||||
|
heart_beat_count integer,
|
||||||
|
position_capability integer,
|
||||||
|
broadcast_push_after_ack bool default false,
|
||||||
|
server_id character varying(50),
|
||||||
|
constraint uk_device_device unique (device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_device_alarm;
|
||||||
|
create table IF NOT EXISTS wvp_device_alarm
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id character varying(50) not null,
|
||||||
|
channel_id character varying(50) not null,
|
||||||
|
alarm_priority character varying(50),
|
||||||
|
alarm_method character varying(50),
|
||||||
|
alarm_time character varying(50),
|
||||||
|
alarm_description character varying(255),
|
||||||
|
longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
alarm_type character varying(50),
|
||||||
|
create_time character varying(50) not null
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_device_mobile_position;
|
||||||
|
create table IF NOT EXISTS wvp_device_mobile_position
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id character varying(50) not null,
|
||||||
|
channel_id character varying(50) not null,
|
||||||
|
device_name character varying(255),
|
||||||
|
time character varying(50),
|
||||||
|
longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
altitude double precision,
|
||||||
|
speed double precision,
|
||||||
|
direction double precision,
|
||||||
|
report_source character varying(50),
|
||||||
|
create_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_device_channel;
|
||||||
|
create table IF NOT EXISTS wvp_device_channel
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id character varying(50),
|
||||||
|
name character varying(255),
|
||||||
|
manufacturer character varying(50),
|
||||||
|
model character varying(50),
|
||||||
|
owner character varying(50),
|
||||||
|
civil_code character varying(50),
|
||||||
|
block character varying(50),
|
||||||
|
address character varying(50),
|
||||||
|
parental integer,
|
||||||
|
parent_id character varying(50),
|
||||||
|
safety_way integer,
|
||||||
|
register_way integer,
|
||||||
|
cert_num character varying(50),
|
||||||
|
certifiable integer,
|
||||||
|
err_code integer,
|
||||||
|
end_time character varying(50),
|
||||||
|
secrecy integer,
|
||||||
|
ip_address character varying(50),
|
||||||
|
port integer,
|
||||||
|
password character varying(255),
|
||||||
|
status character varying(50),
|
||||||
|
longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
ptz_type integer,
|
||||||
|
position_type integer,
|
||||||
|
room_type integer,
|
||||||
|
use_type integer,
|
||||||
|
supply_light_type integer,
|
||||||
|
direction_type integer,
|
||||||
|
resolution character varying(255),
|
||||||
|
business_group_id character varying(255),
|
||||||
|
download_speed character varying(255),
|
||||||
|
svc_space_support_mod integer,
|
||||||
|
svc_time_support_mode integer,
|
||||||
|
create_time character varying(50) not null,
|
||||||
|
update_time character varying(50) not null,
|
||||||
|
sub_count integer,
|
||||||
|
stream_id character varying(255),
|
||||||
|
has_audio bool default false,
|
||||||
|
gps_time character varying(50),
|
||||||
|
stream_identification character varying(50),
|
||||||
|
channel_type int default 0 not null,
|
||||||
|
gb_device_id character varying(50),
|
||||||
|
gb_name character varying(255),
|
||||||
|
gb_manufacturer character varying(255),
|
||||||
|
gb_model character varying(255),
|
||||||
|
gb_owner character varying(255),
|
||||||
|
gb_civil_code character varying(255),
|
||||||
|
gb_block character varying(255),
|
||||||
|
gb_address character varying(255),
|
||||||
|
gb_parental integer,
|
||||||
|
gb_parent_id character varying(255),
|
||||||
|
gb_safety_way integer,
|
||||||
|
gb_register_way integer,
|
||||||
|
gb_cert_num character varying(50),
|
||||||
|
gb_certifiable integer,
|
||||||
|
gb_err_code integer,
|
||||||
|
gb_end_time character varying(50),
|
||||||
|
gb_secrecy integer,
|
||||||
|
gb_ip_address character varying(50),
|
||||||
|
gb_port integer,
|
||||||
|
gb_password character varying(50),
|
||||||
|
gb_status character varying(50),
|
||||||
|
gb_longitude double,
|
||||||
|
gb_latitude double,
|
||||||
|
gb_business_group_id character varying(50),
|
||||||
|
gb_ptz_type integer,
|
||||||
|
gb_position_type integer,
|
||||||
|
gb_room_type integer,
|
||||||
|
gb_use_type integer,
|
||||||
|
gb_supply_light_type integer,
|
||||||
|
gb_direction_type integer,
|
||||||
|
gb_resolution character varying(255),
|
||||||
|
gb_download_speed character varying(255),
|
||||||
|
gb_svc_space_support_mod integer,
|
||||||
|
gb_svc_time_support_mode integer,
|
||||||
|
record_plan_id integer,
|
||||||
|
data_type integer not null,
|
||||||
|
data_device_id integer not null,
|
||||||
|
gps_speed double precision,
|
||||||
|
gps_altitude double precision,
|
||||||
|
gps_direction double precision,
|
||||||
|
index (data_type),
|
||||||
|
index (data_device_id),
|
||||||
|
constraint uk_wvp_unique_channel unique (gb_device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_media_server;
|
||||||
|
create table IF NOT EXISTS wvp_media_server
|
||||||
|
(
|
||||||
|
id character varying(255) primary key,
|
||||||
|
ip character varying(50),
|
||||||
|
hook_ip character varying(50),
|
||||||
|
sdp_ip character varying(50),
|
||||||
|
stream_ip character varying(50),
|
||||||
|
http_port integer,
|
||||||
|
http_ssl_port integer,
|
||||||
|
rtmp_port integer,
|
||||||
|
rtmp_ssl_port integer,
|
||||||
|
rtp_proxy_port integer,
|
||||||
|
rtsp_port integer,
|
||||||
|
rtsp_ssl_port integer,
|
||||||
|
flv_port integer,
|
||||||
|
flv_ssl_port integer,
|
||||||
|
ws_flv_port integer,
|
||||||
|
ws_flv_ssl_port integer,
|
||||||
|
auto_config bool default false,
|
||||||
|
secret character varying(50),
|
||||||
|
type character varying(50) default 'zlm',
|
||||||
|
rtp_enable bool default false,
|
||||||
|
rtp_port_range character varying(50),
|
||||||
|
send_rtp_port_range character varying(50),
|
||||||
|
record_assist_port integer,
|
||||||
|
default_server bool default false,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
hook_alive_interval integer,
|
||||||
|
record_path character varying(255),
|
||||||
|
record_day integer default 7,
|
||||||
|
transcode_suffix character varying(255),
|
||||||
|
server_id character varying(50),
|
||||||
|
constraint uk_media_server_unique_ip_http_port unique (ip, http_port, server_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_platform;
|
||||||
|
create table IF NOT EXISTS wvp_platform
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
enable bool default false,
|
||||||
|
name character varying(255),
|
||||||
|
server_gb_id character varying(50),
|
||||||
|
server_gb_domain character varying(50),
|
||||||
|
server_ip character varying(50),
|
||||||
|
server_port integer,
|
||||||
|
device_gb_id character varying(50),
|
||||||
|
device_ip character varying(50),
|
||||||
|
device_port character varying(50),
|
||||||
|
username character varying(255),
|
||||||
|
password character varying(50),
|
||||||
|
expires character varying(50),
|
||||||
|
keep_timeout character varying(50),
|
||||||
|
transport character varying(50),
|
||||||
|
civil_code character varying(50),
|
||||||
|
manufacturer character varying(255),
|
||||||
|
model character varying(255),
|
||||||
|
address character varying(255),
|
||||||
|
character_set character varying(50),
|
||||||
|
ptz bool default false,
|
||||||
|
rtcp bool default false,
|
||||||
|
status bool default false,
|
||||||
|
catalog_group integer,
|
||||||
|
register_way integer,
|
||||||
|
secrecy integer,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
as_message_channel bool default false,
|
||||||
|
catalog_with_platform integer default 1,
|
||||||
|
catalog_with_group integer default 1,
|
||||||
|
catalog_with_region integer default 1,
|
||||||
|
auto_push_channel bool default true,
|
||||||
|
send_stream_ip character varying(50),
|
||||||
|
server_id character varying(50),
|
||||||
|
constraint uk_platform_unique_server_gb_id unique (server_gb_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_platform_channel;
|
||||||
|
create table IF NOT EXISTS wvp_platform_channel
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
platform_id integer,
|
||||||
|
device_channel_id integer,
|
||||||
|
custom_device_id character varying(50),
|
||||||
|
custom_name character varying(255),
|
||||||
|
custom_manufacturer character varying(50),
|
||||||
|
custom_model character varying(50),
|
||||||
|
custom_owner character varying(50),
|
||||||
|
custom_civil_code character varying(50),
|
||||||
|
custom_block character varying(50),
|
||||||
|
custom_address character varying(50),
|
||||||
|
custom_parental integer,
|
||||||
|
custom_parent_id character varying(50),
|
||||||
|
custom_safety_way integer,
|
||||||
|
custom_register_way integer,
|
||||||
|
custom_cert_num character varying(50),
|
||||||
|
custom_certifiable integer,
|
||||||
|
custom_err_code integer,
|
||||||
|
custom_end_time character varying(50),
|
||||||
|
custom_secrecy integer,
|
||||||
|
custom_ip_address character varying(50),
|
||||||
|
custom_port integer,
|
||||||
|
custom_password character varying(255),
|
||||||
|
custom_status character varying(50),
|
||||||
|
custom_longitude double precision,
|
||||||
|
custom_latitude double precision,
|
||||||
|
custom_ptz_type integer,
|
||||||
|
custom_position_type integer,
|
||||||
|
custom_room_type integer,
|
||||||
|
custom_use_type integer,
|
||||||
|
custom_supply_light_type integer,
|
||||||
|
custom_direction_type integer,
|
||||||
|
custom_resolution character varying(255),
|
||||||
|
custom_business_group_id character varying(255),
|
||||||
|
custom_download_speed character varying(255),
|
||||||
|
custom_svc_space_support_mod integer,
|
||||||
|
custom_svc_time_support_mode integer,
|
||||||
|
constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, device_channel_id),
|
||||||
|
constraint uk_platform_gb_channel_device_id unique (custom_device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_platform_group;
|
||||||
|
create table IF NOT EXISTS wvp_platform_group
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
platform_id integer,
|
||||||
|
group_id integer,
|
||||||
|
constraint uk_wvp_platform_group_platform_id_group_id unique (platform_id, group_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_platform_region;
|
||||||
|
create table IF NOT EXISTS wvp_platform_region
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
platform_id integer,
|
||||||
|
region_id integer,
|
||||||
|
constraint uk_wvp_platform_region_platform_id_group_id unique (platform_id, region_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_stream_proxy;
|
||||||
|
create table IF NOT EXISTS wvp_stream_proxy
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
type character varying(50),
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
src_url character varying(255),
|
||||||
|
timeout integer,
|
||||||
|
ffmpeg_cmd_key character varying(255),
|
||||||
|
rtsp_type character varying(50),
|
||||||
|
media_server_id character varying(50),
|
||||||
|
enable_audio bool default false,
|
||||||
|
enable_mp4 bool default false,
|
||||||
|
pulling bool default false,
|
||||||
|
enable bool default false,
|
||||||
|
enable_remove_none_reader bool default false,
|
||||||
|
create_time character varying(50),
|
||||||
|
name character varying(255),
|
||||||
|
update_time character varying(50),
|
||||||
|
stream_key character varying(255),
|
||||||
|
server_id character varying(50),
|
||||||
|
enable_disable_none_reader bool default false,
|
||||||
|
relates_media_server_id character varying(50),
|
||||||
|
constraint uk_stream_proxy_app_stream unique (app, stream)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_stream_push;
|
||||||
|
create table IF NOT EXISTS wvp_stream_push
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
create_time character varying(50),
|
||||||
|
media_server_id character varying(50),
|
||||||
|
server_id character varying(50),
|
||||||
|
push_time character varying(50),
|
||||||
|
status bool default false,
|
||||||
|
update_time character varying(50),
|
||||||
|
pushing bool default false,
|
||||||
|
self bool default false,
|
||||||
|
start_offline_push bool default true,
|
||||||
|
constraint uk_stream_push_app_stream unique (app, stream)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_cloud_record;
|
||||||
|
create table IF NOT EXISTS wvp_cloud_record
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
call_id character varying(255),
|
||||||
|
start_time bigint,
|
||||||
|
end_time bigint,
|
||||||
|
media_server_id character varying(50),
|
||||||
|
server_id character varying(50),
|
||||||
|
file_name character varying(255),
|
||||||
|
folder character varying(500),
|
||||||
|
file_path character varying(500),
|
||||||
|
collect bool default false,
|
||||||
|
file_size bigint,
|
||||||
|
time_len double precision
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_user;
|
||||||
|
create table IF NOT EXISTS wvp_user
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
username character varying(255),
|
||||||
|
password character varying(255),
|
||||||
|
role_id integer,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
push_key character varying(50),
|
||||||
|
constraint uk_user_username unique (username)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_user_role;
|
||||||
|
create table IF NOT EXISTS wvp_user_role
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
name character varying(50),
|
||||||
|
authority character varying(50),
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_user_api_key;
|
||||||
|
create table IF NOT EXISTS wvp_user_api_key
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
user_id bigint,
|
||||||
|
app character varying(255),
|
||||||
|
api_key text,
|
||||||
|
expired_at bigint,
|
||||||
|
remark character varying(255),
|
||||||
|
enable bool default true,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*初始数据*/
|
||||||
|
INSERT INTO wvp_user
|
||||||
|
VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 1, '2021-04-13 14:14:57', '2021-04-13 14:14:57',
|
||||||
|
'3e80d1762a324d5b0ff636e0bd16f1e3');
|
||||||
|
INSERT INTO wvp_user_role
|
||||||
|
VALUES (1, 'admin', '0', '2021-04-13 14:14:57', '2021-04-13 14:14:57');
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_common_group;
|
||||||
|
create table IF NOT EXISTS wvp_common_group
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id varchar(50) NOT NULL,
|
||||||
|
name varchar(255) NOT NULL,
|
||||||
|
parent_id int,
|
||||||
|
parent_device_id varchar(50) DEFAULT NULL,
|
||||||
|
business_group varchar(50) NOT NULL,
|
||||||
|
create_time varchar(50) NOT NULL,
|
||||||
|
update_time varchar(50) NOT NULL,
|
||||||
|
civil_code varchar(50) default null,
|
||||||
|
constraint uk_common_group_device_platform unique (device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_common_region;
|
||||||
|
create table IF NOT EXISTS wvp_common_region
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id varchar(50) NOT NULL,
|
||||||
|
name varchar(255) NOT NULL,
|
||||||
|
parent_id int,
|
||||||
|
parent_device_id varchar(50) DEFAULT NULL,
|
||||||
|
create_time varchar(50) NOT NULL,
|
||||||
|
update_time varchar(50) NOT NULL,
|
||||||
|
constraint uk_common_region_device_id unique (device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_record_plan;
|
||||||
|
create table IF NOT EXISTS wvp_record_plan
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
snap bool default false,
|
||||||
|
name varchar(255) NOT NULL,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_record_plan_item;
|
||||||
|
create table IF NOT EXISTS wvp_record_plan_item
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
start int,
|
||||||
|
stop int,
|
||||||
|
week_day int,
|
||||||
|
plan_id int,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
467
数据库/2.7.4/初始化-postgresql-kingbase-2.7.4.sql
Normal file
467
数据库/2.7.4/初始化-postgresql-kingbase-2.7.4.sql
Normal file
@@ -0,0 +1,467 @@
|
|||||||
|
/*建表*/
|
||||||
|
drop table IF EXISTS wvp_device;
|
||||||
|
create table IF NOT EXISTS wvp_device
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id character varying(50) not null,
|
||||||
|
name character varying(255),
|
||||||
|
manufacturer character varying(255),
|
||||||
|
model character varying(255),
|
||||||
|
firmware character varying(255),
|
||||||
|
transport character varying(50),
|
||||||
|
stream_mode character varying(50),
|
||||||
|
on_line bool default false,
|
||||||
|
register_time character varying(50),
|
||||||
|
keepalive_time character varying(50),
|
||||||
|
ip character varying(50),
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
port integer,
|
||||||
|
expires integer,
|
||||||
|
subscribe_cycle_for_catalog integer DEFAULT 0,
|
||||||
|
subscribe_cycle_for_mobile_position integer DEFAULT 0,
|
||||||
|
mobile_position_submission_interval integer DEFAULT 5,
|
||||||
|
subscribe_cycle_for_alarm integer DEFAULT 0,
|
||||||
|
host_address character varying(50),
|
||||||
|
charset character varying(50),
|
||||||
|
ssrc_check bool default false,
|
||||||
|
geo_coord_sys character varying(50),
|
||||||
|
media_server_id character varying(50) default 'auto',
|
||||||
|
custom_name character varying(255),
|
||||||
|
sdp_ip character varying(50),
|
||||||
|
local_ip character varying(50),
|
||||||
|
password character varying(255),
|
||||||
|
as_message_channel bool default false,
|
||||||
|
heart_beat_interval integer,
|
||||||
|
heart_beat_count integer,
|
||||||
|
position_capability integer,
|
||||||
|
broadcast_push_after_ack bool default false,
|
||||||
|
server_id character varying(50),
|
||||||
|
constraint uk_device_device unique (device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_device_alarm;
|
||||||
|
create table IF NOT EXISTS wvp_device_alarm
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id character varying(50) not null,
|
||||||
|
channel_id character varying(50) not null,
|
||||||
|
alarm_priority character varying(50),
|
||||||
|
alarm_method character varying(50),
|
||||||
|
alarm_time character varying(50),
|
||||||
|
alarm_description character varying(255),
|
||||||
|
longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
alarm_type character varying(50),
|
||||||
|
create_time character varying(50) not null
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_device_mobile_position;
|
||||||
|
create table IF NOT EXISTS wvp_device_mobile_position
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id character varying(50) not null,
|
||||||
|
channel_id character varying(50) not null,
|
||||||
|
device_name character varying(255),
|
||||||
|
time character varying(50),
|
||||||
|
longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
altitude double precision,
|
||||||
|
speed double precision,
|
||||||
|
direction double precision,
|
||||||
|
report_source character varying(50),
|
||||||
|
create_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_device_channel;
|
||||||
|
create table IF NOT EXISTS wvp_device_channel
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id character varying(50),
|
||||||
|
name character varying(255),
|
||||||
|
manufacturer character varying(50),
|
||||||
|
model character varying(50),
|
||||||
|
owner character varying(50),
|
||||||
|
civil_code character varying(50),
|
||||||
|
block character varying(50),
|
||||||
|
address character varying(50),
|
||||||
|
parental integer,
|
||||||
|
parent_id character varying(50),
|
||||||
|
safety_way integer,
|
||||||
|
register_way integer,
|
||||||
|
cert_num character varying(50),
|
||||||
|
certifiable integer,
|
||||||
|
err_code integer,
|
||||||
|
end_time character varying(50),
|
||||||
|
secrecy integer,
|
||||||
|
ip_address character varying(50),
|
||||||
|
port integer,
|
||||||
|
password character varying(255),
|
||||||
|
status character varying(50),
|
||||||
|
longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
ptz_type integer,
|
||||||
|
position_type integer,
|
||||||
|
room_type integer,
|
||||||
|
use_type integer,
|
||||||
|
supply_light_type integer,
|
||||||
|
direction_type integer,
|
||||||
|
resolution character varying(255),
|
||||||
|
business_group_id character varying(255),
|
||||||
|
download_speed character varying(255),
|
||||||
|
svc_space_support_mod integer,
|
||||||
|
svc_time_support_mode integer,
|
||||||
|
create_time character varying(50) not null,
|
||||||
|
update_time character varying(50) not null,
|
||||||
|
sub_count integer,
|
||||||
|
stream_id character varying(255),
|
||||||
|
has_audio bool default false,
|
||||||
|
gps_time character varying(50),
|
||||||
|
stream_identification character varying(50),
|
||||||
|
channel_type int default 0 not null,
|
||||||
|
gb_device_id character varying(50),
|
||||||
|
gb_name character varying(255),
|
||||||
|
gb_manufacturer character varying(255),
|
||||||
|
gb_model character varying(255),
|
||||||
|
gb_owner character varying(255),
|
||||||
|
gb_civil_code character varying(255),
|
||||||
|
gb_block character varying(255),
|
||||||
|
gb_address character varying(255),
|
||||||
|
gb_parental integer,
|
||||||
|
gb_parent_id character varying(255),
|
||||||
|
gb_safety_way integer,
|
||||||
|
gb_register_way integer,
|
||||||
|
gb_cert_num character varying(50),
|
||||||
|
gb_certifiable integer,
|
||||||
|
gb_err_code integer,
|
||||||
|
gb_end_time character varying(50),
|
||||||
|
gb_secrecy integer,
|
||||||
|
gb_ip_address character varying(50),
|
||||||
|
gb_port integer,
|
||||||
|
gb_password character varying(50),
|
||||||
|
gb_status character varying(50),
|
||||||
|
gb_longitude double precision,
|
||||||
|
gb_latitude double precision,
|
||||||
|
gb_business_group_id character varying(50),
|
||||||
|
gb_ptz_type integer,
|
||||||
|
gb_position_type integer,
|
||||||
|
gb_room_type integer,
|
||||||
|
gb_use_type integer,
|
||||||
|
gb_supply_light_type integer,
|
||||||
|
gb_direction_type integer,
|
||||||
|
gb_resolution character varying(255),
|
||||||
|
gb_download_speed character varying(255),
|
||||||
|
gb_svc_space_support_mod integer,
|
||||||
|
gb_svc_time_support_mode integer,
|
||||||
|
record_plan_id integer,
|
||||||
|
data_type integer not null,
|
||||||
|
data_device_id integer not null,
|
||||||
|
gps_speed double precision,
|
||||||
|
gps_altitude double precision,
|
||||||
|
gps_direction double precision,
|
||||||
|
constraint uk_wvp_unique_channel unique (gb_device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_data_type ON wvp_device_channel (data_type);
|
||||||
|
CREATE INDEX idx_data_device_id ON wvp_device_channel (data_device_id);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_media_server;
|
||||||
|
create table IF NOT EXISTS wvp_media_server
|
||||||
|
(
|
||||||
|
id character varying(255) primary key,
|
||||||
|
ip character varying(50),
|
||||||
|
hook_ip character varying(50),
|
||||||
|
sdp_ip character varying(50),
|
||||||
|
stream_ip character varying(50),
|
||||||
|
http_port integer,
|
||||||
|
http_ssl_port integer,
|
||||||
|
rtmp_port integer,
|
||||||
|
rtmp_ssl_port integer,
|
||||||
|
rtp_proxy_port integer,
|
||||||
|
rtsp_port integer,
|
||||||
|
rtsp_ssl_port integer,
|
||||||
|
flv_port integer,
|
||||||
|
flv_ssl_port integer,
|
||||||
|
ws_flv_port integer,
|
||||||
|
ws_flv_ssl_port integer,
|
||||||
|
auto_config bool default false,
|
||||||
|
secret character varying(50),
|
||||||
|
type character varying(50) default 'zlm',
|
||||||
|
rtp_enable bool default false,
|
||||||
|
rtp_port_range character varying(50),
|
||||||
|
send_rtp_port_range character varying(50),
|
||||||
|
record_assist_port integer,
|
||||||
|
default_server bool default false,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
hook_alive_interval integer,
|
||||||
|
record_path character varying(255),
|
||||||
|
record_day integer default 7,
|
||||||
|
transcode_suffix character varying(255),
|
||||||
|
server_id character varying(50),
|
||||||
|
constraint uk_media_server_unique_ip_http_port unique (ip, http_port, server_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_platform;
|
||||||
|
create table IF NOT EXISTS wvp_platform
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
enable bool default false,
|
||||||
|
name character varying(255),
|
||||||
|
server_gb_id character varying(50),
|
||||||
|
server_gb_domain character varying(50),
|
||||||
|
server_ip character varying(50),
|
||||||
|
server_port integer,
|
||||||
|
device_gb_id character varying(50),
|
||||||
|
device_ip character varying(50),
|
||||||
|
device_port character varying(50),
|
||||||
|
username character varying(255),
|
||||||
|
password character varying(50),
|
||||||
|
expires character varying(50),
|
||||||
|
keep_timeout character varying(50),
|
||||||
|
transport character varying(50),
|
||||||
|
civil_code character varying(50),
|
||||||
|
manufacturer character varying(255),
|
||||||
|
model character varying(255),
|
||||||
|
address character varying(255),
|
||||||
|
character_set character varying(50),
|
||||||
|
ptz bool default false,
|
||||||
|
rtcp bool default false,
|
||||||
|
status bool default false,
|
||||||
|
catalog_group integer,
|
||||||
|
register_way integer,
|
||||||
|
secrecy integer,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
as_message_channel bool default false,
|
||||||
|
catalog_with_platform integer default 1,
|
||||||
|
catalog_with_group integer default 1,
|
||||||
|
catalog_with_region integer default 1,
|
||||||
|
auto_push_channel bool default true,
|
||||||
|
send_stream_ip character varying(50),
|
||||||
|
server_id character varying(50),
|
||||||
|
constraint uk_platform_unique_server_gb_id unique (server_gb_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_platform_channel;
|
||||||
|
create table IF NOT EXISTS wvp_platform_channel
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
platform_id integer,
|
||||||
|
device_channel_id integer,
|
||||||
|
custom_device_id character varying(50),
|
||||||
|
custom_name character varying(255),
|
||||||
|
custom_manufacturer character varying(50),
|
||||||
|
custom_model character varying(50),
|
||||||
|
custom_owner character varying(50),
|
||||||
|
custom_civil_code character varying(50),
|
||||||
|
custom_block character varying(50),
|
||||||
|
custom_address character varying(50),
|
||||||
|
custom_parental integer,
|
||||||
|
custom_parent_id character varying(50),
|
||||||
|
custom_safety_way integer,
|
||||||
|
custom_register_way integer,
|
||||||
|
custom_cert_num character varying(50),
|
||||||
|
custom_certifiable integer,
|
||||||
|
custom_err_code integer,
|
||||||
|
custom_end_time character varying(50),
|
||||||
|
custom_secrecy integer,
|
||||||
|
custom_ip_address character varying(50),
|
||||||
|
custom_port integer,
|
||||||
|
custom_password character varying(255),
|
||||||
|
custom_status character varying(50),
|
||||||
|
custom_longitude double precision,
|
||||||
|
custom_latitude double precision,
|
||||||
|
custom_ptz_type integer,
|
||||||
|
custom_position_type integer,
|
||||||
|
custom_room_type integer,
|
||||||
|
custom_use_type integer,
|
||||||
|
custom_supply_light_type integer,
|
||||||
|
custom_direction_type integer,
|
||||||
|
custom_resolution character varying(255),
|
||||||
|
custom_business_group_id character varying(255),
|
||||||
|
custom_download_speed character varying(255),
|
||||||
|
custom_svc_space_support_mod integer,
|
||||||
|
custom_svc_time_support_mode integer,
|
||||||
|
constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, device_channel_id),
|
||||||
|
constraint uk_platform_gb_channel_device_id unique (custom_device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_platform_group;
|
||||||
|
create table IF NOT EXISTS wvp_platform_group
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
platform_id integer,
|
||||||
|
group_id integer,
|
||||||
|
constraint uk_wvp_platform_group_platform_id_group_id unique (platform_id, group_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_platform_region;
|
||||||
|
create table IF NOT EXISTS wvp_platform_region
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
platform_id integer,
|
||||||
|
region_id integer,
|
||||||
|
constraint uk_wvp_platform_region_platform_id_group_id unique (platform_id, region_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_stream_proxy;
|
||||||
|
create table IF NOT EXISTS wvp_stream_proxy
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
type character varying(50),
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
src_url character varying(255),
|
||||||
|
timeout integer,
|
||||||
|
ffmpeg_cmd_key character varying(255),
|
||||||
|
rtsp_type character varying(50),
|
||||||
|
media_server_id character varying(50),
|
||||||
|
enable_audio bool default false,
|
||||||
|
enable_mp4 bool default false,
|
||||||
|
pulling bool default false,
|
||||||
|
enable bool default false,
|
||||||
|
enable_remove_none_reader bool default false,
|
||||||
|
create_time character varying(50),
|
||||||
|
name character varying(255),
|
||||||
|
update_time character varying(50),
|
||||||
|
stream_key character varying(255),
|
||||||
|
server_id character varying(50),
|
||||||
|
enable_disable_none_reader bool default false,
|
||||||
|
relates_media_server_id character varying(50),
|
||||||
|
constraint uk_stream_proxy_app_stream unique (app, stream)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_stream_push;
|
||||||
|
create table IF NOT EXISTS wvp_stream_push
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
create_time character varying(50),
|
||||||
|
media_server_id character varying(50),
|
||||||
|
server_id character varying(50),
|
||||||
|
push_time character varying(50),
|
||||||
|
status bool default false,
|
||||||
|
update_time character varying(50),
|
||||||
|
pushing bool default false,
|
||||||
|
self bool default false,
|
||||||
|
start_offline_push bool default true,
|
||||||
|
constraint uk_stream_push_app_stream unique (app, stream)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_cloud_record;
|
||||||
|
create table IF NOT EXISTS wvp_cloud_record
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
call_id character varying(255),
|
||||||
|
start_time int8,
|
||||||
|
end_time int8,
|
||||||
|
media_server_id character varying(50),
|
||||||
|
server_id character varying(50),
|
||||||
|
file_name character varying(255),
|
||||||
|
folder character varying(500),
|
||||||
|
file_path character varying(500),
|
||||||
|
collect bool default false,
|
||||||
|
file_size int8,
|
||||||
|
time_len double precision
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_user;
|
||||||
|
create table IF NOT EXISTS wvp_user
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
username character varying(255),
|
||||||
|
password character varying(255),
|
||||||
|
role_id integer,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
push_key character varying(50),
|
||||||
|
constraint uk_user_username unique (username)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_user_role;
|
||||||
|
create table IF NOT EXISTS wvp_user_role
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
name character varying(50),
|
||||||
|
authority character varying(50),
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_user_api_key;
|
||||||
|
create table IF NOT EXISTS wvp_user_api_key
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
user_id int8,
|
||||||
|
app character varying(255),
|
||||||
|
api_key text,
|
||||||
|
expired_at int8,
|
||||||
|
remark character varying(255),
|
||||||
|
enable bool default true,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*初始数据*/
|
||||||
|
INSERT INTO wvp_user
|
||||||
|
VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 1, '2021-04-13 14:14:57', '2021-04-13 14:14:57',
|
||||||
|
'3e80d1762a324d5b0ff636e0bd16f1e3');
|
||||||
|
INSERT INTO wvp_user_role
|
||||||
|
VALUES (1, 'admin', '0', '2021-04-13 14:14:57', '2021-04-13 14:14:57');
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_common_group;
|
||||||
|
create table IF NOT EXISTS wvp_common_group
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id varchar(50) NOT NULL,
|
||||||
|
name varchar(255) NOT NULL,
|
||||||
|
parent_id int,
|
||||||
|
parent_device_id varchar(50) DEFAULT NULL,
|
||||||
|
business_group varchar(50) NOT NULL,
|
||||||
|
create_time varchar(50) NOT NULL,
|
||||||
|
update_time varchar(50) NOT NULL,
|
||||||
|
civil_code varchar(50) default null,
|
||||||
|
constraint uk_common_group_device_platform unique (device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_common_region;
|
||||||
|
create table IF NOT EXISTS wvp_common_region
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
device_id varchar(50) NOT NULL,
|
||||||
|
name varchar(255) NOT NULL,
|
||||||
|
parent_id int,
|
||||||
|
parent_device_id varchar(50) DEFAULT NULL,
|
||||||
|
create_time varchar(50) NOT NULL,
|
||||||
|
update_time varchar(50) NOT NULL,
|
||||||
|
constraint uk_common_region_device_id unique (device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_record_plan;
|
||||||
|
create table IF NOT EXISTS wvp_record_plan
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
snap bool default false,
|
||||||
|
name varchar(255) NOT NULL,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table IF EXISTS wvp_record_plan_item;
|
||||||
|
create table IF NOT EXISTS wvp_record_plan_item
|
||||||
|
(
|
||||||
|
id serial primary key,
|
||||||
|
"start" int,
|
||||||
|
stop int,
|
||||||
|
week_day int,
|
||||||
|
plan_id int,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
Reference in New Issue
Block a user