Merge branch '648540858:wvp-28181-2.0' into wvp-28181-2.0
This commit is contained in:
commit
2d7a202096
@ -47,8 +47,6 @@ public class VideoManagerConstants {
|
||||
public static final String PLATFORM_SEND_RTP_INFO_PREFIX = "VMP_PLATFORM_SEND_RTP_INFO_";
|
||||
|
||||
public static final String EVENT_ONLINE_REGISTER = "1";
|
||||
|
||||
public static final String EVENT_ONLINE_KEEPLIVE = "2";
|
||||
|
||||
public static final String EVENT_ONLINE_MESSAGE = "3";
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.common.ApiSaveConstant;
|
||||
import com.genersoft.iot.vmp.conf.security.SecurityUtils;
|
||||
import com.genersoft.iot.vmp.service.ILogService;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.LogDto;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -16,7 +17,6 @@ import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
@ -26,7 +26,6 @@ public class ApiAccessFilter extends OncePerRequestFilter {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ApiAccessFilter.class);
|
||||
|
||||
private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
@ -58,7 +57,7 @@ public class ApiAccessFilter extends OncePerRequestFilter {
|
||||
logDto.setTiming(System.currentTimeMillis() - start);
|
||||
logDto.setType(servletRequest.getMethod());
|
||||
logDto.setUri(servletRequest.getRequestURI());
|
||||
logDto.setCreateTime(format.format(System.currentTimeMillis()));
|
||||
logDto.setCreateTime(DateUtil.getNow());
|
||||
logService.add(logDto);
|
||||
// logger.warn("[Api Access] [{}] [{}] [{}] [{}] [{}] {}ms",
|
||||
// uriName, servletRequest.getMethod(), servletRequest.getRequestURI(), servletRequest.getRemoteAddr(), HttpStatus.valueOf(servletResponse.getStatus()),
|
||||
|
@ -43,27 +43,27 @@ public class DynamicTask {
|
||||
* 循环执行的任务
|
||||
* @param key 任务ID
|
||||
* @param task 任务
|
||||
* @param cycleForCatalog 间隔
|
||||
* @param cycleForCatalog 间隔 毫秒
|
||||
* @return
|
||||
*/
|
||||
public void startCron(String key, Runnable task, int cycleForCatalog) {
|
||||
ScheduledFuture future = futureMap.get(key);
|
||||
if (future != null) {
|
||||
if (future.isCancelled()) {
|
||||
logger.info("任务【{}】已存在但是关闭状态!!!", key);
|
||||
logger.debug("任务【{}】已存在但是关闭状态!!!", key);
|
||||
} else {
|
||||
logger.info("任务【{}】已存在且已启动!!!", key);
|
||||
logger.debug("任务【{}】已存在且已启动!!!", key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period, cycleForCatalog表示执行的间隔
|
||||
future = threadPoolTaskScheduler.scheduleAtFixedRate(task, cycleForCatalog * 1000L);
|
||||
future = threadPoolTaskScheduler.scheduleAtFixedRate(task, cycleForCatalog);
|
||||
if (future != null){
|
||||
futureMap.put(key, future);
|
||||
runnableMap.put(key, task);
|
||||
logger.info("任务【{}】启动成功!!!", key);
|
||||
logger.debug("任务【{}】启动成功!!!", key);
|
||||
}else {
|
||||
logger.info("任务【{}】启动失败!!!", key);
|
||||
logger.debug("任务【{}】启动失败!!!", key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,9 +81,9 @@ public class DynamicTask {
|
||||
ScheduledFuture future = futureMap.get(key);
|
||||
if (future != null) {
|
||||
if (future.isCancelled()) {
|
||||
logger.info("任务【{}】已存在但是关闭状态!!!", key);
|
||||
logger.debug("任务【{}】已存在但是关闭状态!!!", key);
|
||||
} else {
|
||||
logger.info("任务【{}】已存在且已启动!!!", key);
|
||||
logger.debug("任务【{}】已存在且已启动!!!", key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -92,9 +92,9 @@ public class DynamicTask {
|
||||
if (future != null){
|
||||
futureMap.put(key, future);
|
||||
runnableMap.put(key, task);
|
||||
logger.info("任务【{}】启动成功!!!", key);
|
||||
logger.debug("任务【{}】启动成功!!!", key);
|
||||
}else {
|
||||
logger.info("任务【{}】启动失败!!!", key);
|
||||
logger.debug("任务【{}】启动失败!!!", key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
package com.genersoft.iot.vmp.conf;
|
||||
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
@Configuration("mediaConfig")
|
||||
public class MediaConfig{
|
||||
@ -206,9 +205,8 @@ public class MediaConfig{
|
||||
mediaServerItem.setRecordAssistPort(recordAssistPort);
|
||||
mediaServerItem.setHookAliveInterval(120);
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
mediaServerItem.setCreateTime(format.format(System.currentTimeMillis()));
|
||||
mediaServerItem.setUpdateTime(format.format(System.currentTimeMillis()));
|
||||
mediaServerItem.setCreateTime(DateUtil.getNow());
|
||||
mediaServerItem.setUpdateTime(DateUtil.getNow());
|
||||
|
||||
return mediaServerItem;
|
||||
}
|
||||
|
@ -35,10 +35,11 @@ public class ThreadPoolTaskConfig {
|
||||
* 允许线程空闲时间(单位:默认为秒)
|
||||
*/
|
||||
private static final int keepAliveTime = 30;
|
||||
|
||||
/**
|
||||
* 缓冲队列大小
|
||||
*/
|
||||
private static final int queueCapacity = 500;
|
||||
private static final int queueCapacity = 10000;
|
||||
/**
|
||||
* 线程池名前缀
|
||||
*/
|
||||
|
@ -48,8 +48,15 @@ public class SipLayer{
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
|
||||
properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getMonitorIp());
|
||||
/**
|
||||
* 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码
|
||||
* gov/nist/javax/sip/SipStackImpl.class
|
||||
*/
|
||||
properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
|
||||
properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); // 接收所有notify请求,即使没有订阅
|
||||
properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true"); // 为_NULL _对话框传递_终止的_事件
|
||||
properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal"); // 会话清理策略
|
||||
properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "10");
|
||||
/**
|
||||
* sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE =
|
||||
* 0; public static final int TRACE_MESSAGES = 16; public static final int
|
||||
|
@ -99,11 +99,6 @@ public class Device {
|
||||
*/
|
||||
private String mediaServerId;
|
||||
|
||||
/**
|
||||
* 首次注册
|
||||
*/
|
||||
private boolean firsRegister;
|
||||
|
||||
/**
|
||||
* 字符集, 支持 UTF-8 与 GB2312
|
||||
*/
|
||||
@ -279,14 +274,6 @@ public class Device {
|
||||
this.mediaServerId = mediaServerId;
|
||||
}
|
||||
|
||||
public boolean isFirsRegister() {
|
||||
return firsRegister;
|
||||
}
|
||||
|
||||
public void setFirsRegister(boolean firsRegister) {
|
||||
this.firsRegister = firsRegister;
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
return charset;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@ -116,10 +116,9 @@ public class RecordItem implements Comparable<RecordItem>{
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull RecordItem recordItem) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
try {
|
||||
Date startTime_now = sdf.parse(startTime);
|
||||
Date startTime_param = sdf.parse(recordItem.getStartTime());
|
||||
Date startTime_now = DateUtil.format.parse(startTime);
|
||||
Date startTime_param = DateUtil.format.parse(recordItem.getStartTime());
|
||||
if (startTime_param.compareTo(startTime_now) > 0) {
|
||||
return -1;
|
||||
}else {
|
||||
|
@ -61,7 +61,7 @@ public class SubscribeHolder {
|
||||
// 添加任务处理GPS定时推送
|
||||
dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(redisCatchStorage, sipCommanderForPlatform,
|
||||
storager, platformId, subscribeInfo.getSn(), key, this, dynamicTask),
|
||||
subscribeInfo.getGpsInterval());
|
||||
subscribeInfo.getGpsInterval() * 1000);
|
||||
String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId;
|
||||
dynamicTask.stop(taskOverdueKey);
|
||||
// 添加任务处理订阅过期
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.event.offline.OfflineEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.platformKeepaliveExpire.PlatformKeepaliveExpireEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformCycleRegisterEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.platformNotRegister.PlatformNotRegisterEvent;
|
||||
@ -11,12 +11,11 @@ import com.genersoft.iot.vmp.media.zlm.event.ZLMOfflineEvent;
|
||||
import com.genersoft.iot.vmp.media.zlm.event.ZLMOnlineEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
|
||||
|
||||
import javax.sip.TimeoutEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -32,28 +31,6 @@ public class EventPublisher {
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
public void onlineEventPublish(Device device, String from, int expires) {
|
||||
OnlineEvent onEvent = new OnlineEvent(this);
|
||||
onEvent.setDevice(device);
|
||||
onEvent.setFrom(from);
|
||||
onEvent.setExpires(expires);
|
||||
applicationEventPublisher.publishEvent(onEvent);
|
||||
}
|
||||
|
||||
public void onlineEventPublish(Device device, String from) {
|
||||
OnlineEvent onEvent = new OnlineEvent(this);
|
||||
onEvent.setDevice(device);
|
||||
onEvent.setFrom(from);
|
||||
applicationEventPublisher.publishEvent(onEvent);
|
||||
}
|
||||
|
||||
public void outlineEventPublish(String deviceId, String from){
|
||||
OfflineEvent outEvent = new OfflineEvent(this);
|
||||
outEvent.setDeviceId(deviceId);
|
||||
outEvent.setFrom(from);
|
||||
applicationEventPublisher.publishEvent(outEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台心跳到期事件
|
||||
@ -115,6 +92,13 @@ public class EventPublisher {
|
||||
}
|
||||
|
||||
|
||||
public void requestTimeOut(TimeoutEvent timeoutEvent) {
|
||||
RequestTimeoutEvent requestTimeoutEvent = new RequestTimeoutEvent(this);
|
||||
requestTimeoutEvent.setTimeoutEvent(timeoutEvent);
|
||||
applicationEventPublisher.publishEvent(requestTimeoutEvent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param platformId
|
||||
|
@ -0,0 +1,25 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.device;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import javax.sip.TimeoutEvent;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
*/
|
||||
public class RequestTimeoutEvent extends ApplicationEvent {
|
||||
public RequestTimeoutEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
|
||||
private TimeoutEvent timeoutEvent;
|
||||
|
||||
public TimeoutEvent getTimeoutEvent() {
|
||||
return timeoutEvent;
|
||||
}
|
||||
|
||||
public void setTimeoutEvent(TimeoutEvent timeoutEvent) {
|
||||
this.timeoutEvent = timeoutEvent;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.device;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sip.ClientTransaction;
|
||||
import javax.sip.address.SipURI;
|
||||
import javax.sip.header.CallIdHeader;
|
||||
import javax.sip.header.ToHeader;
|
||||
import javax.sip.message.Request;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
*/
|
||||
@Component
|
||||
public class RequestTimeoutEventImpl implements ApplicationListener<RequestTimeoutEvent> {
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(RequestTimeoutEvent event) {
|
||||
ClientTransaction clientTransaction = event.getTimeoutEvent().getClientTransaction();
|
||||
if (clientTransaction != null) {
|
||||
Request request = clientTransaction.getRequest();
|
||||
if (request != null) {
|
||||
String host = ((SipURI) request.getRequestURI()).getHost();
|
||||
int port = ((SipURI) request.getRequestURI()).getPort();
|
||||
Device device = deviceService.getDeviceByHostAndPort(host, port);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
deviceService.offline(device.getDeviceId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,9 +17,8 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
|
||||
/**
|
||||
* @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
|
||||
* @author: swwheihei
|
||||
* @date: 2020年5月6日 上午11:35:46
|
||||
* 设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
|
||||
* @author swwheihei
|
||||
*/
|
||||
@Component
|
||||
public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEventMessageListener {
|
||||
@ -55,25 +54,18 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent
|
||||
// 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线
|
||||
String PLATFORM_KEEPLIVEKEY_PREFIX = VideoManagerConstants.PLATFORM_KEEPALIVE_PREFIX + userSetting.getServerId() + "_";
|
||||
String PLATFORM_REGISTER_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_PREFIX + userSetting.getServerId() + "_";
|
||||
String KEEPLIVEKEY_PREFIX = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_";
|
||||
String REGISTER_INFO_PREFIX = VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + userSetting.getServerId() + "_";
|
||||
if (expiredKey.startsWith(PLATFORM_KEEPLIVEKEY_PREFIX)) {
|
||||
String platformGBId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
|
||||
ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGBId);
|
||||
String platformGbId = expiredKey.substring(PLATFORM_KEEPLIVEKEY_PREFIX.length());
|
||||
ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId);
|
||||
if (platform != null) {
|
||||
publisher.platformKeepaliveExpireEventPublish(platformGBId);
|
||||
publisher.platformKeepaliveExpireEventPublish(platformGbId);
|
||||
}
|
||||
}else if (expiredKey.startsWith(PLATFORM_REGISTER_PREFIX)) {
|
||||
String platformGBId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
|
||||
ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGBId);
|
||||
String platformGbId = expiredKey.substring(PLATFORM_REGISTER_PREFIX.length(),expiredKey.length());
|
||||
ParentPlatform platform = storager.queryParentPlatByServerGBId(platformGbId);
|
||||
if (platform != null) {
|
||||
publisher.platformRegisterCycleEventPublish(platformGBId);
|
||||
}
|
||||
}else if (expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){
|
||||
String deviceId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
if (device != null) {
|
||||
publisher.outlineEventPublish(deviceId, KEEPLIVEKEY_PREFIX);
|
||||
publisher.platformRegisterCycleEventPublish(platformGbId);
|
||||
}
|
||||
}else if (expiredKey.startsWith(REGISTER_INFO_PREFIX)) {
|
||||
String callId = expiredKey.substring(REGISTER_INFO_PREFIX.length());
|
||||
@ -85,6 +77,5 @@ public class KeepaliveTimeoutListenerForPlatform extends RedisKeyExpirationEvent
|
||||
sipSubscribe.getErrorSubscribe(callId).response(eventResult);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +0,0 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.offline;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.RedisKeyExpirationEventMessageListener;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.connection.Message;
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
|
||||
/**
|
||||
* @description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
|
||||
* @author: swwheihei
|
||||
* @date: 2020年5月6日 上午11:35:46
|
||||
*/
|
||||
@Component
|
||||
public class KeepliveTimeoutListener extends RedisKeyExpirationEventMessageListener {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(KeepliveTimeoutListener.class);
|
||||
|
||||
@Autowired
|
||||
private EventPublisher publisher;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
public KeepliveTimeoutListener(RedisMessageListenerContainer listenerContainer, UserSetting userSetting) {
|
||||
super(listenerContainer, userSetting);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (!userSetting.getRedisConfig()) {
|
||||
// 配置springboot默认Config为空,即不让应用去修改redis的默认配置,因为Redis服务出于安全会禁用CONFIG命令给远程用户使用
|
||||
setKeyspaceNotificationsConfigParameter("");
|
||||
}
|
||||
super.init();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 监听失效的key,key格式为keeplive_deviceId
|
||||
* @param message
|
||||
* @param pattern
|
||||
*/
|
||||
@Override
|
||||
public void onMessage(Message message, byte[] pattern) {
|
||||
// 获取失效的key
|
||||
String expiredKey = message.toString();
|
||||
String KEEPLIVEKEY_PREFIX = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_";
|
||||
if(!expiredKey.startsWith(KEEPLIVEKEY_PREFIX)){
|
||||
logger.debug("收到redis过期监听,但开头不是"+KEEPLIVEKEY_PREFIX+",忽略");
|
||||
return;
|
||||
}
|
||||
|
||||
String deviceId = expiredKey.substring(KEEPLIVEKEY_PREFIX.length(),expiredKey.length());
|
||||
publisher.outlineEventPublish(deviceId, VideoManagerConstants.EVENT_OUTLINE_TIMEOUT);
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.offline;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @description: 离线事件类
|
||||
* @author: swwheihei
|
||||
* @date: 2020年5月6日 上午11:33:13
|
||||
*/
|
||||
public class OfflineEvent extends ApplicationEvent {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public OfflineEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String from;
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.offline;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
|
||||
* 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor}
|
||||
* 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener}
|
||||
* @author: swwheihei
|
||||
* @date: 2020年5月6日 下午1:51:23
|
||||
*/
|
||||
@Component
|
||||
public class OfflineEventListener implements ApplicationListener<OfflineEvent> {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(OfflineEventListener.class);
|
||||
|
||||
@Autowired
|
||||
private IVideoManagerStorage storager;
|
||||
|
||||
@Autowired
|
||||
private VideoStreamSessionManager streamSession;
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redis;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Autowired
|
||||
private EventPublisher eventPublisher;
|
||||
|
||||
|
||||
@Autowired
|
||||
private IMediaServerService mediaServerService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ZLMRTPServerFactory zlmrtpServerFactory;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(OfflineEvent event) {
|
||||
|
||||
logger.info("设备离线事件触发,deviceId:" + event.getDeviceId() + ",from:" + event.getFrom());
|
||||
|
||||
String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + event.getDeviceId();
|
||||
|
||||
switch (event.getFrom()) {
|
||||
// 心跳超时触发的离线事件,说明redis中已删除,无需处理
|
||||
case VideoManagerConstants.EVENT_OUTLINE_TIMEOUT:
|
||||
break;
|
||||
// 设备主动注销触发的离线事件,需要删除redis中的超时监听
|
||||
case VideoManagerConstants.EVENT_OUTLINE_UNREGISTER:
|
||||
redis.del(key);
|
||||
break;
|
||||
default:
|
||||
boolean exist = redis.hasKey(key);
|
||||
if (exist) {
|
||||
redis.del(key);
|
||||
}
|
||||
}
|
||||
|
||||
List<DeviceChannel> deviceChannelList = storager.queryOnlineChannelsByDeviceId(event.getDeviceId());
|
||||
eventPublisher.catalogEventPublish(null, deviceChannelList, CatalogEvent.OFF);
|
||||
// 处理离线监听
|
||||
storager.outline(event.getDeviceId());
|
||||
|
||||
// TODO 离线取消订阅
|
||||
|
||||
// 离线释放所有ssrc
|
||||
List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(event.getDeviceId(), null, null, null);
|
||||
if (ssrcTransactions != null && ssrcTransactions.size() > 0) {
|
||||
for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
|
||||
mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
|
||||
mediaServerService.closeRTPServer(event.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
|
||||
streamSession.remove(event.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.online;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @description: 在线事件类
|
||||
* @author: swwheihei
|
||||
* @date: 2020年5月6日 上午11:32:56
|
||||
*/
|
||||
public class OnlineEvent extends ApplicationEvent {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public OnlineEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
private Device device;
|
||||
|
||||
private String from;
|
||||
|
||||
private int expires;
|
||||
|
||||
public Device getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public void setDevice(Device device) {
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public int getExpires() {
|
||||
return expires;
|
||||
}
|
||||
|
||||
public void setExpires(int expires) {
|
||||
this.expires = expires;
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.online;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
|
||||
* 1、设备主动注销,发送注销指令
|
||||
* 2、设备未知原因离线,心跳超时
|
||||
* @author: swwheihei
|
||||
* @date: 2020年5月6日 下午1:51:23
|
||||
*/
|
||||
@Component
|
||||
public class OnlineEventListener implements ApplicationListener<OnlineEvent> {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(OnlineEventListener.class);
|
||||
|
||||
@Autowired
|
||||
private IVideoManagerStorage storager;
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redis;
|
||||
|
||||
@Autowired
|
||||
private SipConfig sipConfig;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Autowired
|
||||
private EventPublisher eventPublisher;
|
||||
|
||||
@Autowired
|
||||
private SIPCommander cmder;
|
||||
|
||||
|
||||
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(OnlineEvent event) {
|
||||
|
||||
logger.info("设备上线事件触发,deviceId:" + event.getDevice().getDeviceId() + ",from:" + event.getFrom());
|
||||
Device device = event.getDevice();
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + event.getDevice().getDeviceId();
|
||||
Device deviceInStore = storager.queryVideoDevice(device.getDeviceId());
|
||||
device.setOnline(1);
|
||||
switch (event.getFrom()) {
|
||||
// 注册时触发的在线事件,先在redis中增加超时超时监听
|
||||
case VideoManagerConstants.EVENT_ONLINE_REGISTER:
|
||||
// 超时时间
|
||||
redis.set(key, event.getDevice().getDeviceId(), sipConfig.getKeepaliveTimeOut());
|
||||
device.setRegisterTime(format.format(System.currentTimeMillis()));
|
||||
if (deviceInStore == null) { //第一次上线
|
||||
logger.info("[{}] 首次注册,查询设备信息以及通道信息", device.getDeviceId());
|
||||
cmder.deviceInfoQuery(device);
|
||||
deviceService.sync(device);
|
||||
}
|
||||
break;
|
||||
// 设备主动发送心跳触发的在线事件
|
||||
case VideoManagerConstants.EVENT_ONLINE_KEEPLIVE:
|
||||
boolean exist = redis.hasKey(key);
|
||||
// 先判断是否还存在,当设备先心跳超时后又发送心跳时,redis没有监听,需要增加
|
||||
if (!exist) {
|
||||
redis.set(key, event.getDevice().getDeviceId(), sipConfig.getKeepaliveTimeOut());
|
||||
} else {
|
||||
redis.expire(key, sipConfig.getKeepaliveTimeOut());
|
||||
}
|
||||
device.setKeepaliveTime(format.format(System.currentTimeMillis()));
|
||||
break;
|
||||
// 设备主动发送消息触发的在线事件
|
||||
case VideoManagerConstants.EVENT_ONLINE_MESSAGE:
|
||||
|
||||
break;
|
||||
}
|
||||
// 处理上线监听
|
||||
storager.updateDevice(device);
|
||||
// 上线添加订阅
|
||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
||||
// 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
|
||||
deviceService.addCatalogSubscribe(device);
|
||||
}
|
||||
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
||||
deviceService.addMobilePositionSubscribe(device);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.genersoft.iot.vmp.conf.runner;
|
||||
package com.genersoft.iot.vmp.gb28181.task;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
@ -10,11 +10,13 @@ import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 系统启动时控制设备
|
||||
* @author lin
|
||||
*/
|
||||
@Component
|
||||
@Order(value=4)
|
||||
@ -34,26 +36,16 @@ public class SipDeviceRunner implements CommandLineRunner {
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
// 读取redis没有心跳信息的则设置为离线,等收到下次心跳设置为在线
|
||||
// 设置所有设备离线
|
||||
storager.outlineForAll();
|
||||
List<String> onlineForAll = redisCatchStorage.getOnlineForAll();
|
||||
for (String deviceId : onlineForAll) {
|
||||
storager.online(deviceId);
|
||||
Device device = redisCatchStorage.getDevice(deviceId);
|
||||
if (device != null ) {
|
||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
||||
// 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
|
||||
deviceService.addCatalogSubscribe(device);
|
||||
}
|
||||
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
||||
deviceService.addMobilePositionSubscribe(device);
|
||||
}
|
||||
List<Device> deviceList = deviceService.getAllOnlineDevice();
|
||||
|
||||
for (Device device : deviceList) {
|
||||
if (deviceService.expire(device)){
|
||||
deviceService.offline(device.getDeviceId());
|
||||
}else {
|
||||
deviceService.online(device);
|
||||
}
|
||||
}
|
||||
// 重置cseq计数
|
||||
redisCatchStorage.resetAllCSEQ();
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.RegisterRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd.KeepaliveNotifyMessageHandler;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.response.ISIPResponseProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
|
||||
import org.slf4j.Logger;
|
||||
@ -11,10 +14,13 @@ import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sip.*;
|
||||
import javax.sip.header.CSeqHeader;
|
||||
import javax.sip.header.CallIdHeader;
|
||||
import javax.sip.address.SipURI;
|
||||
import javax.sip.address.URI;
|
||||
import javax.sip.header.*;
|
||||
import javax.sip.message.Request;
|
||||
import javax.sip.message.Response;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@ -34,10 +40,11 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
|
||||
@Autowired
|
||||
private SipSubscribe sipSubscribe;
|
||||
|
||||
@Autowired
|
||||
private EventPublisher eventPublisher;
|
||||
|
||||
|
||||
|
||||
// @Autowired
|
||||
// @Qualifier(value = "taskExecutor")
|
||||
// private ThreadPoolTaskExecutor poolTaskExecutor;
|
||||
|
||||
/**
|
||||
* 添加 request订阅
|
||||
@ -141,9 +148,32 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
|
||||
*/
|
||||
@Override
|
||||
public void processTimeout(TimeoutEvent timeoutEvent) {
|
||||
if(timeoutProcessor != null) {
|
||||
timeoutProcessor.process(timeoutEvent);
|
||||
logger.info("[消息发送超时]");
|
||||
ClientTransaction clientTransaction = timeoutEvent.getClientTransaction();
|
||||
eventPublisher.requestTimeOut(timeoutEvent);
|
||||
if (clientTransaction != null) {
|
||||
Request request = clientTransaction.getRequest();
|
||||
if (request != null) {
|
||||
CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
|
||||
if (callIdHeader != null) {
|
||||
SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId());
|
||||
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(timeoutEvent);
|
||||
subscribe.response(eventResult);
|
||||
sipSubscribe.removeErrorSubscribe(callIdHeader.getCallId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Timeout timeout = timeoutEvent.getTimeout();
|
||||
// ServerTransaction serverTransaction = timeoutEvent.getServerTransaction();
|
||||
// if (serverTransaction != null) {
|
||||
// Request request = serverTransaction.getRequest();
|
||||
// URI requestURI = request.getRequestURI();
|
||||
// Header header = request.getHeader(FromHeader.NAME);
|
||||
// }
|
||||
// if(timeoutProcessor != null) {
|
||||
// timeoutProcessor.process(timeoutEvent);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
@ -27,7 +27,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.SpringBootVersion;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||
|
@ -23,6 +23,7 @@ import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
|
||||
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.SerializeUtils;
|
||||
import gov.nist.javax.sdp.TimeDescriptionImpl;
|
||||
import gov.nist.javax.sdp.fields.TimeField;
|
||||
@ -39,7 +40,6 @@ import javax.sip.header.CallIdHeader;
|
||||
import javax.sip.message.Request;
|
||||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Vector;
|
||||
|
||||
@ -335,9 +335,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
||||
sendRtpItem.setStreamId(ssrcInfo.getStream());
|
||||
// 写入redis, 超时时回复
|
||||
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, format.format(start),
|
||||
format.format(end), null, result -> {
|
||||
playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.format.format(start),
|
||||
DateUtil.format.format(end), null, result -> {
|
||||
if (result.getCode() != 0){
|
||||
logger.warn("录像回放失败");
|
||||
if (result.getEvent() != null) {
|
||||
|
@ -252,14 +252,12 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
|
||||
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
||||
String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader);
|
||||
|
||||
Element rootElement = getRootElement(evt);
|
||||
Device device = redisCatchStorage.getDevice(deviceId);
|
||||
if (device == null) {
|
||||
if (device == null || device.getOnline() == 0) {
|
||||
logger.warn("[收到 目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" ));
|
||||
return;
|
||||
}
|
||||
if (device != null ) {
|
||||
rootElement = getRootElement(evt, device.getCharset());
|
||||
}
|
||||
Element rootElement = getRootElement(evt, device.getCharset());
|
||||
Element deviceListElement = rootElement.element("DeviceList");
|
||||
if (deviceListElement == null) {
|
||||
return;
|
||||
@ -279,39 +277,46 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
|
||||
channel.setDeviceId(device.getDeviceId());
|
||||
logger.info("[收到 目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId());
|
||||
switch (eventElement.getText().toUpperCase()) {
|
||||
case CatalogEvent.ON: // 上线
|
||||
case CatalogEvent.ON:
|
||||
// 上线
|
||||
logger.info("收到来自设备【{}】的通道【{}】上线通知", device.getDeviceId(), channel.getChannelId());
|
||||
storager.deviceChannelOnline(deviceId, channel.getChannelId());
|
||||
// 回复200 OK
|
||||
responseAck(evt, Response.OK);
|
||||
break;
|
||||
case CatalogEvent.OFF : // 离线
|
||||
case CatalogEvent.OFF :
|
||||
// 离线
|
||||
logger.info("收到来自设备【{}】的通道【{}】离线通知", device.getDeviceId(), channel.getChannelId());
|
||||
storager.deviceChannelOffline(deviceId, channel.getChannelId());
|
||||
// 回复200 OK
|
||||
responseAck(evt, Response.OK);
|
||||
break;
|
||||
case CatalogEvent.VLOST: // 视频丢失
|
||||
case CatalogEvent.VLOST:
|
||||
// 视频丢失
|
||||
logger.info("收到来自设备【{}】的通道【{}】视频丢失通知", device.getDeviceId(), channel.getChannelId());
|
||||
storager.deviceChannelOffline(deviceId, channel.getChannelId());
|
||||
// 回复200 OK
|
||||
responseAck(evt, Response.OK);
|
||||
break;
|
||||
case CatalogEvent.DEFECT: // 故障
|
||||
case CatalogEvent.DEFECT:
|
||||
// 故障
|
||||
// 回复200 OK
|
||||
responseAck(evt, Response.OK);
|
||||
break;
|
||||
case CatalogEvent.ADD: // 增加
|
||||
case CatalogEvent.ADD:
|
||||
// 增加
|
||||
logger.info("收到来自设备【{}】的增加通道【{}】通知", device.getDeviceId(), channel.getChannelId());
|
||||
storager.updateChannel(deviceId, channel);
|
||||
responseAck(evt, Response.OK);
|
||||
break;
|
||||
case CatalogEvent.DEL: // 删除
|
||||
case CatalogEvent.DEL:
|
||||
// 删除
|
||||
logger.info("收到来自设备【{}】的删除通道【{}】通知", device.getDeviceId(), channel.getChannelId());
|
||||
storager.delChannel(deviceId, channel.getChannelId());
|
||||
responseAck(evt, Response.OK);
|
||||
break;
|
||||
case CatalogEvent.UPDATE: // 更新
|
||||
case CatalogEvent.UPDATE:
|
||||
// 更新
|
||||
logger.info("收到来自设备【{}】的更新通道【{}】通知", device.getDeviceId(), channel.getChannelId());
|
||||
storager.updateChannel(deviceId, channel);
|
||||
responseAck(evt, Response.OK);
|
||||
@ -324,10 +329,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
|
||||
eventPublisher.catalogEventPublish(null, channel, eventElement.getText().toUpperCase());
|
||||
|
||||
}
|
||||
|
||||
if (!redisCatchStorage.deviceIsOnline(deviceId)) {
|
||||
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
||||
}
|
||||
}
|
||||
} catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import gov.nist.javax.sip.RequestEventExt;
|
||||
@ -60,6 +61,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
||||
@Autowired
|
||||
private SIPProcessorObserver sipProcessorObserver;
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// 添加消息处理的订阅
|
||||
@ -82,7 +86,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
||||
Response response = null;
|
||||
boolean passwordCorrect = false;
|
||||
// 注册标志 0:未携带授权头或者密码错误 1:注册成功 2:注销成功
|
||||
int registerFlag = 0;
|
||||
boolean registerFlag = false;
|
||||
FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);
|
||||
AddressImpl address = (AddressImpl) fromHeader.getAddress();
|
||||
SipUri uri = (SipUri) address.getURI();
|
||||
@ -111,12 +115,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
||||
return;
|
||||
}
|
||||
|
||||
Device deviceInRedis = redisCatchStorage.getDevice(deviceId);
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
if (deviceInRedis != null && device == null) {
|
||||
// redis 存在脏数据
|
||||
redisCatchStorage.clearCatchByDeviceId(deviceId);
|
||||
}
|
||||
Device device = deviceService.queryDevice(deviceId);
|
||||
|
||||
// 携带授权头并且密码正确
|
||||
response = getMessageFactory().createResponse(Response.OK, request);
|
||||
// 添加date头
|
||||
@ -154,20 +154,17 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
||||
device.setStreamMode("UDP");
|
||||
device.setCharset("GB2312");
|
||||
device.setDeviceId(deviceId);
|
||||
device.setFirsRegister(true);
|
||||
} else {
|
||||
device.setFirsRegister(device.getOnline() == 0);
|
||||
}
|
||||
device.setIp(received);
|
||||
device.setPort(rPort);
|
||||
device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
|
||||
if (expiresHeader.getExpires() == 0) {
|
||||
// 注销成功
|
||||
registerFlag = 2;
|
||||
registerFlag = false;
|
||||
} else {
|
||||
// 注册成功
|
||||
device.setExpires(expiresHeader.getExpires());
|
||||
registerFlag = 1;
|
||||
registerFlag = true;
|
||||
// 判断TCP还是UDP
|
||||
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
|
||||
String transport = reqViaHeader.getTransport();
|
||||
@ -177,12 +174,12 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
||||
sendResponse(evt, response);
|
||||
// 注册成功
|
||||
// 保存到redis
|
||||
if (registerFlag == 1) {
|
||||
if (registerFlag) {
|
||||
logger.info("[{}] 注册成功! deviceId:" + deviceId, requestAddress);
|
||||
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_REGISTER, expiresHeader.getExpires());
|
||||
} else if (registerFlag == 2) {
|
||||
deviceService.online(device);
|
||||
} else {
|
||||
logger.info("[{}] 注销成功! deviceId:" + deviceId, requestAddress);
|
||||
publisher.outlineEventPublish(deviceId, VideoManagerConstants.EVENT_OUTLINE_UNREGISTER);
|
||||
deviceService.offline(deviceId);
|
||||
}
|
||||
} catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -1,14 +1,15 @@
|
||||
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.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
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.notify.NotifyMessageHandler;
|
||||
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import org.dom4j.Element;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -23,24 +24,20 @@ import javax.sip.SipException;
|
||||
import javax.sip.header.ViaHeader;
|
||||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
@Component
|
||||
public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class);
|
||||
private final String cmdType = "Keepalive";
|
||||
private final static String cmdType = "Keepalive";
|
||||
|
||||
@Autowired
|
||||
private NotifyMessageHandler notifyMessageHandler;
|
||||
|
||||
@Autowired
|
||||
private EventPublisher publisher;
|
||||
|
||||
@Autowired
|
||||
private IVideoManagerStorage videoManagerStorager;
|
||||
|
||||
@Autowired
|
||||
private IRedisCatchStorage redisCatchStorage;
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
@ -49,29 +46,35 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
|
||||
|
||||
@Override
|
||||
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||
// 检查设备是否存在并在线, 不在线则设置为在线
|
||||
if (device == null) {
|
||||
// 未注册的设备不做处理
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (device != null ) {
|
||||
if (device.getOnline() == 1) {
|
||||
// 回复200 OK
|
||||
responseAck(evt, Response.OK);
|
||||
// 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息
|
||||
// 获取到通信地址等信息
|
||||
ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME);
|
||||
String received = viaHeader.getReceived();
|
||||
int rPort = viaHeader.getRPort();
|
||||
// 解析本地地址替代
|
||||
if (StringUtils.isEmpty(received) || rPort == -1) {
|
||||
received = viaHeader.getHost();
|
||||
rPort = viaHeader.getPort();
|
||||
}
|
||||
if (device.getPort() != rPort) {
|
||||
device.setPort(rPort);
|
||||
device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
|
||||
videoManagerStorager.updateDevice(device);
|
||||
redisCatchStorage.updateDevice(device);
|
||||
}
|
||||
if (!redisCatchStorage.deviceIsOnline(device.getDeviceId())) {
|
||||
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
||||
}else {
|
||||
// 对于已经离线的设备判断他的注册是否已经过期
|
||||
if (!deviceService.expire(device)){
|
||||
device.setKeepaliveTime(DateUtil.getNow());
|
||||
// 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息
|
||||
// 获取到通信地址等信息
|
||||
ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME);
|
||||
String received = viaHeader.getReceived();
|
||||
int rPort = viaHeader.getRPort();
|
||||
// 解析本地地址替代
|
||||
if (StringUtils.isEmpty(received) || rPort == -1) {
|
||||
received = viaHeader.getHost();
|
||||
rPort = viaHeader.getPort();
|
||||
}
|
||||
if (device.getPort() != rPort) {
|
||||
device.setPort(rPort);
|
||||
device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));
|
||||
}
|
||||
deviceService.online(device);
|
||||
// 回复200 OK
|
||||
responseAck(evt, Response.OK);
|
||||
}
|
||||
}
|
||||
} catch (SipException e) {
|
||||
|
@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||
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.query.QueryMessageHandler;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo;
|
||||
import org.dom4j.Element;
|
||||
|
@ -28,7 +28,6 @@ import javax.sip.RequestEvent;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -39,8 +38,6 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
|
||||
private Logger logger = LoggerFactory.getLogger(CatalogResponseMessageHandler.class);
|
||||
private final String cmdType = "Catalog";
|
||||
|
||||
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Autowired
|
||||
private ResponseMessageHandler responseMessageHandler;
|
||||
|
||||
|
@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
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.response.ResponseMessageHandler;
|
||||
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import org.dom4j.DocumentException;
|
||||
@ -29,6 +30,9 @@ import java.text.ParseException;
|
||||
|
||||
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
*/
|
||||
@Component
|
||||
public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||
|
||||
@ -53,6 +57,9 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
|
||||
@Autowired
|
||||
private EventPublisher publisher;
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
responseMessageHandler.addHandler(cmdType, this);
|
||||
@ -61,6 +68,11 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
|
||||
@Override
|
||||
public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
|
||||
logger.debug("接收到DeviceInfo应答消息");
|
||||
// 检查设备是否存在, 不存在则不回复
|
||||
if (device == null || device.getOnline() == 0) {
|
||||
logger.warn("[接收到DeviceInfo应答消息,但是设备已经离线]:" + (device != null ? device.getDeviceId():"" ));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
rootElement = getRootElement(evt, device.getCharset());
|
||||
Element deviceIdElement = rootElement.element("DeviceID");
|
||||
@ -74,7 +86,8 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
|
||||
if (StringUtils.isEmpty(device.getStreamMode())) {
|
||||
device.setStreamMode("UDP");
|
||||
}
|
||||
storager.updateDevice(device);
|
||||
deviceService.updateDevice(device);
|
||||
// storager.updateDevice(device);
|
||||
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setKey(key);
|
||||
@ -82,9 +95,6 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent
|
||||
deferredResultHolder.invokeAllResult(msg);
|
||||
// 回复200 OK
|
||||
responseAck(evt, Response.OK);
|
||||
if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) {
|
||||
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
||||
}
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidArgumentException e) {
|
||||
|
@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import org.dom4j.Element;
|
||||
import org.slf4j.Logger;
|
||||
@ -24,6 +25,7 @@ import javax.sip.RequestEvent;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
import java.util.Objects;
|
||||
|
||||
@Component
|
||||
public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||
@ -34,12 +36,11 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen
|
||||
@Autowired
|
||||
private ResponseMessageHandler responseMessageHandler;
|
||||
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder deferredResultHolder;
|
||||
|
||||
@Autowired
|
||||
private EventPublisher publisher;
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private IRedisCatchStorage redisCatchStorage;
|
||||
@ -53,6 +54,9 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen
|
||||
public void handForDevice(RequestEvent evt, Device device, Element element) {
|
||||
logger.info("接收到DeviceStatus应答消息");
|
||||
// 检查设备是否存在, 不存在则不回复
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
// 回复200 OK
|
||||
try {
|
||||
responseAck(evt, Response.OK);
|
||||
@ -64,20 +68,23 @@ public class DeviceStatusResponseMessageHandler extends SIPRequestProcessorParen
|
||||
e.printStackTrace();
|
||||
}
|
||||
Element deviceIdElement = element.element("DeviceID");
|
||||
Element onlineElement = element.element("Online");
|
||||
String channelId = deviceIdElement.getText();
|
||||
JSONObject json = new JSONObject();
|
||||
XmlUtil.node2Json(element, json);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(json.toJSONString());
|
||||
}
|
||||
String text = onlineElement.getText();
|
||||
if (Objects.equals(text.trim().toUpperCase(), "ONLINE")) {
|
||||
deviceService.online(device);
|
||||
}else {
|
||||
deviceService.offline(device.getDeviceId());
|
||||
}
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setKey(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + device.getDeviceId() + channelId);
|
||||
msg.setData(json);
|
||||
deferredResultHolder.invokeAllResult(msg);
|
||||
|
||||
if (redisCatchStorage.deviceIsOnline(device.getDeviceId())) {
|
||||
publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,7 +20,6 @@ import javax.sip.RequestEvent;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -33,8 +32,6 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
|
||||
private Logger logger = LoggerFactory.getLogger(PresetQueryResponseMessageHandler.class);
|
||||
private final String cmdType = "PresetQuery";
|
||||
|
||||
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Autowired
|
||||
private ResponseMessageHandler responseMessageHandler;
|
||||
|
||||
|
@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
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.response.ResponseMessageHandler;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.Element;
|
||||
|
@ -55,9 +55,6 @@ public class ZLMRunner implements CommandLineRunner {
|
||||
@Autowired
|
||||
private DynamicTask dynamicTask;
|
||||
|
||||
@Qualifier("taskExecutor")
|
||||
@Autowired
|
||||
private ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
@Override
|
||||
public void run(String... strings) throws Exception {
|
||||
@ -105,9 +102,7 @@ public class ZLMRunner implements CommandLineRunner {
|
||||
startGetMedia = new HashMap<>();
|
||||
}
|
||||
startGetMedia.put(mediaServerItem.getId(), true);
|
||||
taskExecutor.execute(()->{
|
||||
connectZlmServer(mediaServerItem);
|
||||
});
|
||||
connectZlmServer(mediaServerItem);
|
||||
}
|
||||
String taskKey = "zlm-connect-timeout";
|
||||
dynamicTask.startDelay(taskKey, ()->{
|
||||
@ -119,21 +114,37 @@ public class ZLMRunner implements CommandLineRunner {
|
||||
startGetMedia = null;
|
||||
}
|
||||
// TODO 清理数据库中与redis不匹配的zlm
|
||||
}, 6 * 1000 );
|
||||
}, 60 * 1000 );
|
||||
}
|
||||
|
||||
@Async
|
||||
public void connectZlmServer(MediaServerItem mediaServerItem){
|
||||
ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem, 1);
|
||||
if (zlmServerConfig != null) {
|
||||
zlmServerConfig.setIp(mediaServerItem.getIp());
|
||||
zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort());
|
||||
String connectZlmServerTaskKey = "connect-zlm-" + mediaServerItem.getId();
|
||||
ZLMServerConfig zlmServerConfigFirst = getMediaServerConfig(mediaServerItem);
|
||||
if (zlmServerConfigFirst != null) {
|
||||
zlmServerConfigFirst.setIp(mediaServerItem.getIp());
|
||||
zlmServerConfigFirst.setHttpPort(mediaServerItem.getHttpPort());
|
||||
startGetMedia.remove(mediaServerItem.getId());
|
||||
mediaServerService.zlmServerOnline(zlmServerConfig);
|
||||
mediaServerService.zlmServerOnline(zlmServerConfigFirst);
|
||||
}else {
|
||||
logger.info("[ {} ]-[ {}:{} ]主动连接失败, 清理相关资源, 开始尝试重试连接",
|
||||
mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
|
||||
publisher.zlmOfflineEventPublish(mediaServerItem.getId());
|
||||
}
|
||||
|
||||
dynamicTask.startCron(connectZlmServerTaskKey, ()->{
|
||||
ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem);
|
||||
if (zlmServerConfig != null) {
|
||||
dynamicTask.stop(connectZlmServerTaskKey);
|
||||
zlmServerConfig.setIp(mediaServerItem.getIp());
|
||||
zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort());
|
||||
startGetMedia.remove(mediaServerItem.getId());
|
||||
mediaServerService.zlmServerOnline(zlmServerConfig);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem, int index) {
|
||||
public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) {
|
||||
if (startGetMedia == null) { return null;}
|
||||
if (!mediaServerItem.isDefaultServer() && mediaServerService.getOne(mediaServerItem.getId()) == null) {
|
||||
return null;
|
||||
@ -149,53 +160,10 @@ public class ZLMRunner implements CommandLineRunner {
|
||||
zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
|
||||
}
|
||||
} else {
|
||||
logger.error("[ {} ]-[ {}:{} ]第{}次主动连接失败, 2s后重试",
|
||||
mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort(), index);
|
||||
if (index == 1 && !StringUtils.isEmpty(mediaServerItem.getId())) {
|
||||
logger.info("[ {} ]-[ {}:{} ]第{}次主动连接失败, 开始清理相关资源",
|
||||
mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort(), index);
|
||||
publisher.zlmOfflineEventPublish(mediaServerItem.getId());
|
||||
}
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
zlmServerConfig = getMediaServerConfig(mediaServerItem, index += 1);
|
||||
logger.error("[ {} ]-[ {}:{} ]主动连接失败, 2s后重试",
|
||||
mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
|
||||
}
|
||||
return zlmServerConfig;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* zlm 连接成功或者zlm重启后
|
||||
*/
|
||||
// private void zLmRunning(ZLMServerConfig zlmServerConfig){
|
||||
// logger.info( "[ id: " + zlmServerConfig.getGeneralMediaServerId() + "] zlm接入成功...");
|
||||
// // 关闭循环获取zlm配置
|
||||
// startGetMedia = false;
|
||||
// MediaServerItem mediaServerItem = new MediaServerItem(zlmServerConfig, sipIp);
|
||||
// storager.updateMediaServer(mediaServerItem);
|
||||
//
|
||||
// if (mediaServerItem.isAutoConfig()) setZLMConfig(mediaServerItem);
|
||||
// zlmServerManger.updateServerCatchFromHook(zlmServerConfig);
|
||||
//
|
||||
// // 清空所有session
|
||||
//// zlmMediaListManager.clearAllSessions();
|
||||
//
|
||||
// // 更新流列表
|
||||
// zlmMediaListManager.updateMediaList(mediaServerItem);
|
||||
// // 恢复流代理, 只查找这个这个流媒体
|
||||
// List<StreamProxyItem> streamProxyListForEnable = storager.getStreamProxyListForEnableInMediaServer(
|
||||
// mediaServerItem.getId(), true);
|
||||
// for (StreamProxyItem streamProxyDto : streamProxyListForEnable) {
|
||||
// logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
|
||||
// JSONObject jsonObject = streamProxyService.addStreamProxyToZlm(streamProxyDto);
|
||||
// if (jsonObject == null) {
|
||||
// // 设置为未启用
|
||||
// logger.info("恢复流代理失败,请检查流地址后重新启用" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
|
||||
// streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@ -7,12 +7,10 @@ import com.genersoft.iot.vmp.service.IStreamPushService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
/**
|
||||
* @description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
|
||||
@ -38,13 +36,11 @@ public class ZLMStatusEventListener {
|
||||
@Autowired
|
||||
private IPlayService playService;
|
||||
|
||||
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void onApplicationEvent(ZLMOnlineEvent event) {
|
||||
|
||||
logger.info("ZLM上线事件触发,ID:" + event.getMediaServerId());
|
||||
logger.info("【ZLM上线】ID:" + event.getMediaServerId());
|
||||
streamPushService.zlmServerOnline(event.getMediaServerId());
|
||||
streamProxyService.zlmServerOnline(event.getMediaServerId());
|
||||
|
||||
|
@ -3,56 +3,111 @@ package com.genersoft.iot.vmp.service;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SyncStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备相关业务处理
|
||||
* @author lin
|
||||
*/
|
||||
public interface IDeviceService {
|
||||
|
||||
/**
|
||||
* 设备上线
|
||||
* @param device 设备信息
|
||||
*/
|
||||
void online(Device device);
|
||||
|
||||
/**
|
||||
* 设备下线
|
||||
* @param deviceId 设备编号
|
||||
*/
|
||||
void offline(String deviceId);
|
||||
|
||||
/**
|
||||
* 添加目录订阅
|
||||
* @param device 设备信息
|
||||
* @return
|
||||
* @return 布尔
|
||||
*/
|
||||
boolean addCatalogSubscribe(Device device);
|
||||
|
||||
/**
|
||||
* 移除目录订阅
|
||||
* @param device 设备信息
|
||||
* @return
|
||||
* @return 布尔
|
||||
*/
|
||||
boolean removeCatalogSubscribe(Device device);
|
||||
|
||||
/**
|
||||
* 添加移动位置订阅
|
||||
* @param device 设备信息
|
||||
* @return
|
||||
* @return 布尔
|
||||
*/
|
||||
boolean addMobilePositionSubscribe(Device device);
|
||||
|
||||
/**
|
||||
* 移除移动位置订阅
|
||||
* @param device 设备信息
|
||||
* @return
|
||||
* @return 布尔
|
||||
*/
|
||||
boolean removeMobilePositionSubscribe(Device device);
|
||||
|
||||
/**
|
||||
* 移除移动位置订阅
|
||||
* @param deviceId 设备ID
|
||||
* @return
|
||||
* @return 同步状态
|
||||
*/
|
||||
SyncStatus getChannelSyncStatus(String deviceId);
|
||||
|
||||
/**
|
||||
* 查看是否仍在同步
|
||||
* @param deviceId 设备ID
|
||||
* @return
|
||||
* @return 布尔
|
||||
*/
|
||||
Boolean isSyncRunning(String deviceId);
|
||||
|
||||
/**
|
||||
* 通道同步
|
||||
* @param device
|
||||
* @param device 设备信息
|
||||
*/
|
||||
void sync(Device device);
|
||||
|
||||
/**
|
||||
* 查询设备信息
|
||||
* @param deviceId 设备编号
|
||||
* @return 设备信息
|
||||
*/
|
||||
Device queryDevice(String deviceId);
|
||||
|
||||
/**
|
||||
* 获取所有在线设备
|
||||
* @return 设备列表
|
||||
*/
|
||||
List<Device> getAllOnlineDevice();
|
||||
|
||||
/**
|
||||
* 判断是否注册已经失效
|
||||
* @param device 设备信息
|
||||
* @return 布尔
|
||||
*/
|
||||
boolean expire(Device device);
|
||||
|
||||
/**
|
||||
* 检查设备状态
|
||||
* @param device 设备信息
|
||||
*/
|
||||
void checkDeviceStatus(Device device);
|
||||
|
||||
/**
|
||||
* 根据IP和端口获取设备信息
|
||||
* @param host IP
|
||||
* @param port 端口
|
||||
* @return 设备信息
|
||||
*/
|
||||
Device getDeviceByHostAndPort(String host, int port);
|
||||
|
||||
/**
|
||||
* 更新设备
|
||||
* @param device 设备信息
|
||||
*/
|
||||
void updateDevice(Device device);
|
||||
}
|
||||
|
@ -2,21 +2,33 @@ package com.genersoft.iot.vmp.service.impl;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler;
|
||||
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask;
|
||||
import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SyncStatus;
|
||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.IMediaService;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.sip.DialogState;
|
||||
import javax.sip.TimeoutEvent;
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备业务(目录订阅)
|
||||
@ -26,6 +38,8 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);
|
||||
|
||||
private final String registerExpireTaskKeyPrefix = "device-register-expire-";
|
||||
|
||||
@Autowired
|
||||
private DynamicTask dynamicTask;
|
||||
|
||||
@ -38,6 +52,90 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
@Autowired
|
||||
private IRedisCatchStorage redisCatchStorage;
|
||||
|
||||
@Autowired
|
||||
private DeviceMapper deviceMapper;
|
||||
|
||||
@Autowired
|
||||
private ISIPCommander commander;
|
||||
|
||||
@Autowired
|
||||
private VideoStreamSessionManager streamSession;
|
||||
|
||||
@Autowired
|
||||
private IMediaServerService mediaServerService;
|
||||
|
||||
@Override
|
||||
public void online(Device device) {
|
||||
logger.info("[设备上线],deviceId:" + device.getDeviceId());
|
||||
Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId());
|
||||
Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
|
||||
|
||||
String now = DateUtil.getNow();
|
||||
if (deviceInRedis != null && deviceInDb == null) {
|
||||
// redis 存在脏数据
|
||||
redisCatchStorage.clearCatchByDeviceId(device.getDeviceId());
|
||||
|
||||
}
|
||||
if (device.getRegisterTime() == null) {
|
||||
device.setRegisterTime(now);
|
||||
}
|
||||
if(device.getUpdateTime() == null) {
|
||||
device.setUpdateTime(now);
|
||||
}
|
||||
device.setOnline(1);
|
||||
|
||||
// 第一次上线
|
||||
if (device.getCreateTime() == null) {
|
||||
device.setCreateTime(now);
|
||||
logger.info("[设备上线,首次注册]: {},查询设备信息以及通道信息", device.getDeviceId());
|
||||
commander.deviceInfoQuery(device);
|
||||
sync(device);
|
||||
deviceMapper.add(device);
|
||||
}else {
|
||||
deviceMapper.update(device);
|
||||
}
|
||||
redisCatchStorage.updateDevice(device);
|
||||
// 上线添加订阅
|
||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
||||
// 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
|
||||
addCatalogSubscribe(device);
|
||||
}
|
||||
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
||||
addMobilePositionSubscribe(device);
|
||||
}
|
||||
// 刷新过期任务
|
||||
String registerExpireTaskKey = registerExpireTaskKeyPrefix + device.getDeviceId();
|
||||
dynamicTask.stop(registerExpireTaskKey);
|
||||
dynamicTask.startDelay(registerExpireTaskKey, ()->{
|
||||
offline(device.getDeviceId());
|
||||
}, device.getExpires() * 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offline(String deviceId) {
|
||||
Device device = deviceMapper.getDeviceByDeviceId(deviceId);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
String registerExpireTaskKey = registerExpireTaskKeyPrefix + deviceId;
|
||||
dynamicTask.stop(registerExpireTaskKey);
|
||||
device.setOnline(0);
|
||||
redisCatchStorage.updateDevice(device);
|
||||
deviceMapper.update(device);
|
||||
// 离线释放所有ssrc
|
||||
List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(deviceId, null, null, null);
|
||||
if (ssrcTransactions != null && ssrcTransactions.size() > 0) {
|
||||
for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
|
||||
mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
|
||||
mediaServerService.closeRTPServer(deviceId, ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
|
||||
streamSession.remove(deviceId, ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
|
||||
}
|
||||
}
|
||||
// 移除订阅
|
||||
removeCatalogSubscribe(device);
|
||||
removeMobilePositionSubscribe(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addCatalogSubscribe(Device device) {
|
||||
if (device == null || device.getSubscribeCycleForCatalog() < 0) {
|
||||
@ -49,7 +147,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
// 提前开始刷新订阅
|
||||
int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForCatalog(),30);
|
||||
// 设置最小值为30
|
||||
dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, subscribeCycleForCatalog -1);
|
||||
dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, (subscribeCycleForCatalog -1) * 1000);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -74,7 +172,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
// 设置最小值为30
|
||||
int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForMobilePosition(),30);
|
||||
// 提前开始刷新订阅
|
||||
dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, subscribeCycleForCatalog -1 );
|
||||
dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, (subscribeCycleForCatalog -1 ) * 1000);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -111,4 +209,101 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Device queryDevice(String deviceId) {
|
||||
return deviceMapper.getDeviceByDeviceId(deviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Device> getAllOnlineDevice() {
|
||||
return deviceMapper.getOnlineDevices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean expire(Device device) {
|
||||
Date registerTimeDate;
|
||||
try {
|
||||
registerTimeDate = DateUtil.format.parse(device.getRegisterTime());
|
||||
} catch (ParseException e) {
|
||||
logger.error("设备时间格式化失败:{}->{} ", device.getDeviceId(), device.getRegisterTime() );
|
||||
return false;
|
||||
}
|
||||
int expires = device.getExpires();
|
||||
Calendar calendarForExpire = Calendar.getInstance();
|
||||
calendarForExpire.setTime(registerTimeDate);
|
||||
calendarForExpire.set(Calendar.SECOND, calendarForExpire.get(Calendar.SECOND) + expires);
|
||||
return calendarForExpire.before(DateUtil.getNow());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkDeviceStatus(Device device) {
|
||||
if (device == null || device.getOnline() == 0) {
|
||||
return;
|
||||
}
|
||||
sipCommander.deviceStatusQuery(device, null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Device getDeviceByHostAndPort(String host, int port) {
|
||||
return deviceMapper.getDeviceByHostAndPort(host, port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDevice(Device device) {
|
||||
|
||||
Device deviceInStore = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
|
||||
if (deviceInStore == null) {
|
||||
logger.warn("更新设备时未找到设备信息");
|
||||
return;
|
||||
}
|
||||
if (!StringUtils.isEmpty(device.getName())) {
|
||||
deviceInStore.setName(device.getName());
|
||||
}
|
||||
if (!StringUtils.isEmpty(device.getCharset())) {
|
||||
deviceInStore.setCharset(device.getCharset());
|
||||
}
|
||||
if (!StringUtils.isEmpty(device.getMediaServerId())) {
|
||||
deviceInStore.setMediaServerId(device.getMediaServerId());
|
||||
}
|
||||
|
||||
// 目录订阅相关的信息
|
||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
||||
if (deviceInStore.getSubscribeCycleForCatalog() == 0 || deviceInStore.getSubscribeCycleForCatalog() != device.getSubscribeCycleForCatalog()) {
|
||||
deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
|
||||
// 开启订阅
|
||||
addCatalogSubscribe(deviceInStore);
|
||||
}
|
||||
}else if (device.getSubscribeCycleForCatalog() == 0) {
|
||||
if (deviceInStore.getSubscribeCycleForCatalog() != 0) {
|
||||
deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
|
||||
// 取消订阅
|
||||
removeCatalogSubscribe(deviceInStore);
|
||||
}
|
||||
}
|
||||
|
||||
// 移动位置订阅相关的信息
|
||||
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
||||
if (deviceInStore.getSubscribeCycleForMobilePosition() == 0 || deviceInStore.getSubscribeCycleForMobilePosition() != device.getSubscribeCycleForMobilePosition()) {
|
||||
deviceInStore.setMobilePositionSubmissionInterval(device.getMobilePositionSubmissionInterval());
|
||||
deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition());
|
||||
// 开启订阅
|
||||
addMobilePositionSubscribe(deviceInStore);
|
||||
}
|
||||
}else if (device.getSubscribeCycleForMobilePosition() == 0) {
|
||||
if (deviceInStore.getSubscribeCycleForMobilePosition() != 0) {
|
||||
// 取消订阅
|
||||
removeMobilePositionSubscribe(deviceInStore);
|
||||
}
|
||||
}
|
||||
|
||||
String now = DateUtil.getNow();
|
||||
device.setUpdateTime(now);
|
||||
device.setCharset(device.getCharset().toUpperCase());
|
||||
device.setUpdateTime(DateUtil.getNow());
|
||||
if (deviceMapper.update(device) > 0) {
|
||||
redisCatchStorage.updateDevice(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.service.IStreamProxyService;
|
||||
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.storager.dao.MediaServerMapper;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.redis.JedisUtil;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
@ -89,8 +90,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
||||
@Autowired
|
||||
JedisUtil jedisUtil;
|
||||
|
||||
private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
@ -231,7 +230,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
||||
result.sort((serverItem1, serverItem2)->{
|
||||
int sortResult = 0;
|
||||
try {
|
||||
sortResult = format.parse(serverItem1.getCreateTime()).compareTo(format.parse(serverItem2.getCreateTime()));
|
||||
sortResult = DateUtil.format.parse(serverItem1.getCreateTime()).compareTo(DateUtil.format.parse(serverItem2.getCreateTime()));
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -291,8 +290,8 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
||||
@Override
|
||||
public WVPResult<String> add(MediaServerItem mediaServerItem) {
|
||||
WVPResult<String> result = new WVPResult<>();
|
||||
mediaServerItem.setCreateTime(this.format.format(System.currentTimeMillis()));
|
||||
mediaServerItem.setUpdateTime(this.format.format(System.currentTimeMillis()));
|
||||
mediaServerItem.setCreateTime(DateUtil.getNow());
|
||||
mediaServerItem.setUpdateTime(DateUtil.getNow());
|
||||
mediaServerItem.setHookAliveInterval(120);
|
||||
JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
|
||||
if (responseJSON != null) {
|
||||
|
@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
||||
|
@ -4,20 +4,15 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.connection.Message;
|
||||
import org.springframework.data.redis.connection.MessageListener;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
@Component
|
||||
public class RedisAlarmMsgListener implements MessageListener {
|
||||
@ -33,8 +28,6 @@ public class RedisAlarmMsgListener implements MessageListener {
|
||||
@Autowired
|
||||
private IVideoManagerStorage storage;
|
||||
|
||||
private final SimpleDateFormat formatForGB = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message, byte[] bytes) {
|
||||
logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody()));
|
||||
@ -52,7 +45,7 @@ public class RedisAlarmMsgListener implements MessageListener {
|
||||
deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription());
|
||||
deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());
|
||||
deviceAlarm.setAlarmPriority("1");
|
||||
deviceAlarm.setAlarmTime(formatForGB.format(System.currentTimeMillis()));
|
||||
deviceAlarm.setAlarmTime(DateUtil.getNow());
|
||||
deviceAlarm.setAlarmType("1");
|
||||
deviceAlarm.setLongitude(0);
|
||||
deviceAlarm.setLatitude(0);
|
||||
|
@ -111,23 +111,6 @@ public interface IRedisCatchStorage {
|
||||
*/
|
||||
void clearCatchByDeviceId(String deviceId);
|
||||
|
||||
/**
|
||||
* 获取mediaServer节点
|
||||
* @param mediaServerId
|
||||
* @return
|
||||
*/
|
||||
// MediaServerItem getMediaInfo(String mediaServerId);
|
||||
|
||||
/**
|
||||
* 设置所有设备离线
|
||||
*/
|
||||
void outlineForAll();
|
||||
|
||||
/**
|
||||
* 获取所有在线的
|
||||
*/
|
||||
List<String> getOnlineForAll();
|
||||
|
||||
/**
|
||||
* 在redis添加wvp的信息
|
||||
*/
|
||||
|
@ -25,22 +25,6 @@ public interface IVideoManagerStorage {
|
||||
* @return true:存在 false:不存在
|
||||
*/
|
||||
public boolean exists(String deviceId);
|
||||
|
||||
/**
|
||||
* 视频设备创建
|
||||
*
|
||||
* @param device 设备对象
|
||||
* @return true:创建成功 false:创建失败
|
||||
*/
|
||||
public boolean create(Device device);
|
||||
|
||||
/**
|
||||
* 视频设备更新
|
||||
*
|
||||
* @param device 设备对象
|
||||
* @return true:创建成功 false:创建失败
|
||||
*/
|
||||
public boolean updateDevice(Device device);
|
||||
|
||||
/**
|
||||
* 添加设备通道
|
||||
|
@ -99,4 +99,9 @@ public interface DeviceMapper {
|
||||
|
||||
@Update("UPDATE device SET online=0")
|
||||
int outlineForAll();
|
||||
|
||||
@Select("SELECT * FROM device WHERE online = 1")
|
||||
List<Device> getOnlineDevices();
|
||||
@Select("SELECT * FROM device WHERE ip = #{host} AND port=${port}")
|
||||
Device getDeviceByHostAndPort(String host, int port);
|
||||
}
|
||||
|
@ -14,13 +14,13 @@ import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
|
||||
import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@ -38,8 +38,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Override
|
||||
public Long getCSEQ(String method) {
|
||||
String key = VideoManagerConstants.SIP_CSEQ_PREFIX + userSetting.getServerId() + "_" + method;
|
||||
@ -469,26 +467,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void outlineForAll() {
|
||||
List<Object> onlineDevices = redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + "*" );
|
||||
for (int i = 0; i < onlineDevices.size(); i++) {
|
||||
String key = (String) onlineDevices.get(i);
|
||||
redis.del(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getOnlineForAll() {
|
||||
List<String> result = new ArrayList<>();
|
||||
List<Object> onlineDevices = redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + "*" );
|
||||
for (int i = 0; i < onlineDevices.size(); i++) {
|
||||
String key = (String) onlineDevices.get(i);
|
||||
result.add((String) redis.get(key));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateWVPInfo(JSONObject jsonObject, int time) {
|
||||
String key = VideoManagerConstants.WVP_SERVER_PREFIX + userSetting.getServerId();
|
||||
@ -638,7 +616,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
||||
public void addCpuInfo(double cpuInfo) {
|
||||
String key = VideoManagerConstants.SYSTEM_INFO_CPU_PREFIX + userSetting.getServerId();
|
||||
SystemInfoDto<Double> systemInfoDto = new SystemInfoDto<>();
|
||||
systemInfoDto.setTime(format.format(System.currentTimeMillis()));
|
||||
systemInfoDto.setTime(DateUtil.getNow());
|
||||
systemInfoDto.setData(cpuInfo);
|
||||
redis.lSet(key, systemInfoDto);
|
||||
// 每秒一个,最多只存30个
|
||||
@ -653,7 +631,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
||||
public void addMemInfo(double memInfo) {
|
||||
String key = VideoManagerConstants.SYSTEM_INFO_MEM_PREFIX + userSetting.getServerId();
|
||||
SystemInfoDto<Double> systemInfoDto = new SystemInfoDto<>();
|
||||
systemInfoDto.setTime(format.format(System.currentTimeMillis()));
|
||||
systemInfoDto.setTime(DateUtil.getNow());
|
||||
systemInfoDto.setData(memInfo);
|
||||
redis.lSet(key, systemInfoDto);
|
||||
// 每秒一个,最多只存30个
|
||||
@ -668,7 +646,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
||||
public void addNetInfo(Map<String, String> networkInterfaces) {
|
||||
String key = VideoManagerConstants.SYSTEM_INFO_NET_PREFIX + userSetting.getServerId();
|
||||
SystemInfoDto<Map<String, String>> systemInfoDto = new SystemInfoDto<>();
|
||||
systemInfoDto.setTime(format.format(System.currentTimeMillis()));
|
||||
systemInfoDto.setTime(DateUtil.getNow());
|
||||
systemInfoDto.setData(networkInterfaces);
|
||||
redis.lSet(key, systemInfoDto);
|
||||
// 每秒一个,最多只存30个
|
||||
@ -702,7 +680,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
||||
|
||||
@Override
|
||||
public boolean deviceIsOnline(String deviceId) {
|
||||
String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + deviceId;
|
||||
return redis.hasKey(key);
|
||||
return getDevice(deviceId).getOnline() == 1;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.storager.dao.*;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
@ -26,7 +27,6 @@ import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@ -91,9 +91,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
|
||||
@Autowired
|
||||
private ParentPlatformMapper parentPlatformMapper;
|
||||
|
||||
private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
|
||||
/**
|
||||
* 根据设备ID判断设备是否存在
|
||||
*
|
||||
@ -105,45 +102,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
|
||||
return deviceMapper.getDeviceByDeviceId(deviceId) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频设备创建
|
||||
*
|
||||
* @param device 设备对象
|
||||
* @return true:创建成功 false:创建失败
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean create(Device device) {
|
||||
redisCatchStorage.updateDevice(device);
|
||||
return deviceMapper.add(device) > 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 视频设备更新
|
||||
*
|
||||
* @param device 设备对象
|
||||
* @return true:更新成功 false:更新失败
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean updateDevice(Device device) {
|
||||
String now = this.format.format(System.currentTimeMillis());
|
||||
device.setUpdateTime(now);
|
||||
Device deviceByDeviceId = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
|
||||
device.setCharset(device.getCharset().toUpperCase());
|
||||
if (deviceByDeviceId == null) {
|
||||
device.setCreateTime(now);
|
||||
redisCatchStorage.updateDevice(device);
|
||||
return deviceMapper.add(device) > 0;
|
||||
}else {
|
||||
redisCatchStorage.updateDevice(device);
|
||||
|
||||
return deviceMapper.update(device) > 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void updateChannel(String deviceId, DeviceChannel channel) {
|
||||
String channelId = channel.getChannelId();
|
||||
@ -152,7 +110,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
|
||||
if (streamInfo != null) {
|
||||
channel.setStreamId(streamInfo.getStream());
|
||||
}
|
||||
String now = this.format.format(System.currentTimeMillis());
|
||||
String now = DateUtil.getNow();
|
||||
channel.setUpdateTime(now);
|
||||
DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId);
|
||||
if (deviceChannel == null) {
|
||||
@ -178,7 +136,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
|
||||
if (streamInfo != null) {
|
||||
channel.setStreamId(streamInfo.getStream());
|
||||
}
|
||||
String now = this.format.format(System.currentTimeMillis());
|
||||
String now = DateUtil.getNow();
|
||||
channel.setUpdateTime(now);
|
||||
channel.setCreateTime(now);
|
||||
addChannels.add(channel);
|
||||
@ -193,7 +151,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
|
||||
if (streamInfo != null) {
|
||||
channel.setStreamId(streamInfo.getStream());
|
||||
}
|
||||
String now = this.format.format(System.currentTimeMillis());
|
||||
String now = DateUtil.getNow();
|
||||
channel.setUpdateTime(now);
|
||||
if (channelsInStore.get(channel.getChannelId()) != null) {
|
||||
updateChannels.add(channel);
|
||||
@ -732,7 +690,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
|
||||
boolean result = false;
|
||||
streamProxyItem.setStreamType("proxy");
|
||||
streamProxyItem.setStatus(true);
|
||||
String now = this.format.format(System.currentTimeMillis());
|
||||
String now = DateUtil.getNow();
|
||||
streamProxyItem.setCreateTime(now);
|
||||
streamProxyItem.setCreateStamp(System.currentTimeMillis());
|
||||
try {
|
||||
|
@ -1,57 +1,57 @@
|
||||
package com.genersoft.iot.vmp.gb28181.utils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @description:时间工具类,主要处理ISO 8601格式转换
|
||||
* @author: swwheihei
|
||||
* @date: 2020年5月8日 下午3:24:42
|
||||
*/
|
||||
public class DateUtil {
|
||||
|
||||
//private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
|
||||
private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss";
|
||||
private static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
|
||||
|
||||
SimpleDateFormat oldsdf = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault());
|
||||
SimpleDateFormat newsdf = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault());
|
||||
try {
|
||||
return newsdf.format(oldsdf.parse(formatTime));
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) {
|
||||
|
||||
SimpleDateFormat oldsdf = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault());
|
||||
SimpleDateFormat newsdf = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault());
|
||||
try {
|
||||
return newsdf.format(oldsdf.parse(formatTime));
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static long yyyy_MM_dd_HH_mm_ssToTimestamp(String formatTime) {
|
||||
SimpleDateFormat format=new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss);
|
||||
//设置要读取的时间字符串格式
|
||||
Date date;
|
||||
try {
|
||||
date = format.parse(formatTime);
|
||||
Long timestamp=date.getTime()/1000;
|
||||
//转换为Date类
|
||||
return timestamp;
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
package com.genersoft.iot.vmp.utils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 全局时间工具类
|
||||
* @author swwheihei
|
||||
*/
|
||||
public class DateUtil {
|
||||
|
||||
private static final String yyyy_MM_dd_T_HH_mm_ss_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss";
|
||||
private static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public static final SimpleDateFormat formatISO8601 = new SimpleDateFormat(yyyy_MM_dd_T_HH_mm_ss_SSSXXX, Locale.getDefault());
|
||||
public static final SimpleDateFormat format = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss, Locale.getDefault());
|
||||
|
||||
public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
|
||||
|
||||
try {
|
||||
return formatISO8601.format(format.parse(formatTime));
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String ISO8601Toyyyy_MM_dd_HH_mm_ss(String formatTime) {
|
||||
|
||||
try {
|
||||
return format.format(formatISO8601.parse(formatTime));
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static long yyyy_MM_dd_HH_mm_ssToTimestamp(String formatTime) {
|
||||
//设置要读取的时间字符串格式
|
||||
Date date;
|
||||
try {
|
||||
date = format.parse(formatTime);
|
||||
Long timestamp=date.getTime()/1000;
|
||||
//转换为Date类
|
||||
return timestamp;
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static String getNow() {
|
||||
return format.format(System.currentTimeMillis());
|
||||
}
|
||||
}
|
@ -169,7 +169,7 @@ public class MobilePositionController {
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
device.setSubscribeCycleForMobilePosition(Integer.parseInt(expires));
|
||||
device.setMobilePositionSubmissionInterval(Integer.parseInt(interval));
|
||||
storager.updateDevice(device);
|
||||
deviceService.updateDevice(device);
|
||||
String result = msg;
|
||||
if (deviceService.removeMobilePositionSubscribe(device)) {
|
||||
result += ",成功";
|
||||
|
@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
||||
import com.genersoft.iot.vmp.service.IGbStreamService;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import io.swagger.annotations.Api;
|
||||
@ -23,9 +24,7 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "报警信息管理")
|
||||
@ -46,9 +45,6 @@ public class AlarmController {
|
||||
@Autowired
|
||||
private IVideoManagerStorage storage;
|
||||
|
||||
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
private SimpleDateFormat formatForGB = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||
|
||||
/**
|
||||
* 分页查询报警
|
||||
*
|
||||
@ -104,10 +100,10 @@ public class AlarmController {
|
||||
|
||||
try {
|
||||
if (startTime != null) {
|
||||
format.parse(startTime);
|
||||
DateUtil.format.parse(startTime);
|
||||
}
|
||||
if (endTime != null) {
|
||||
format.parse(endTime);
|
||||
DateUtil.format.parse(endTime);
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
|
||||
@ -150,7 +146,7 @@ public class AlarmController {
|
||||
}
|
||||
try {
|
||||
if (time != null) {
|
||||
format.parse(time);
|
||||
DateUtil.format.parse(time);
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
|
||||
@ -193,7 +189,7 @@ public class AlarmController {
|
||||
deviceAlarm.setAlarmDescription("test");
|
||||
deviceAlarm.setAlarmMethod("1");
|
||||
deviceAlarm.setAlarmPriority("1");
|
||||
deviceAlarm.setAlarmTime(formatForGB.format(System.currentTimeMillis()));
|
||||
deviceAlarm.setAlarmTime(DateUtil.formatISO8601.format(System.currentTimeMillis()));
|
||||
deviceAlarm.setAlarmType("1");
|
||||
deviceAlarm.setLongitude(115.33333);
|
||||
deviceAlarm.setLatitude(39.33333);
|
||||
|
@ -288,7 +288,8 @@ public class DeviceQuery {
|
||||
public ResponseEntity<PageInfo> updateTransport(@PathVariable String deviceId, @PathVariable String streamMode){
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
device.setStreamMode(streamMode);
|
||||
storager.updateDevice(device);
|
||||
// storager.updateDevice(device);
|
||||
deviceService.updateDevice(device);
|
||||
return new ResponseEntity<>(null,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ -305,51 +306,12 @@ public class DeviceQuery {
|
||||
public ResponseEntity<WVPResult<String>> updateDevice(Device device){
|
||||
|
||||
if (device != null && device.getDeviceId() != null) {
|
||||
Device deviceInStore = storager.queryVideoDevice(device.getDeviceId());
|
||||
if (!StringUtils.isEmpty(device.getName())) {
|
||||
deviceInStore.setName(device.getName());
|
||||
}
|
||||
if (!StringUtils.isEmpty(device.getCharset())) {
|
||||
deviceInStore.setCharset(device.getCharset());
|
||||
}
|
||||
if (!StringUtils.isEmpty(device.getMediaServerId())) {
|
||||
deviceInStore.setMediaServerId(device.getMediaServerId());
|
||||
}
|
||||
|
||||
// 目录订阅相关的信息
|
||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
||||
if (deviceInStore.getSubscribeCycleForCatalog() == 0 || deviceInStore.getSubscribeCycleForCatalog() != device.getSubscribeCycleForCatalog()) {
|
||||
deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
|
||||
// 开启订阅
|
||||
deviceService.addCatalogSubscribe(deviceInStore);
|
||||
}
|
||||
}else if (device.getSubscribeCycleForCatalog() == 0) {
|
||||
if (deviceInStore.getSubscribeCycleForCatalog() != 0) {
|
||||
deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
|
||||
// 取消订阅
|
||||
deviceService.removeCatalogSubscribe(deviceInStore);
|
||||
}
|
||||
}
|
||||
|
||||
// 移动位置订阅相关的信息
|
||||
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
||||
if (deviceInStore.getSubscribeCycleForMobilePosition() == 0 || deviceInStore.getSubscribeCycleForMobilePosition() != device.getSubscribeCycleForMobilePosition()) {
|
||||
deviceInStore.setMobilePositionSubmissionInterval(device.getMobilePositionSubmissionInterval());
|
||||
deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition());
|
||||
// 开启订阅
|
||||
deviceService.addMobilePositionSubscribe(deviceInStore);
|
||||
}
|
||||
}else if (device.getSubscribeCycleForMobilePosition() == 0) {
|
||||
if (deviceInStore.getSubscribeCycleForMobilePosition() != 0) {
|
||||
// 取消订阅
|
||||
deviceService.removeMobilePositionSubscribe(deviceInStore);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 报警订阅相关的信息
|
||||
|
||||
storager.updateDevice(device);
|
||||
cmder.deviceInfoQuery(device);
|
||||
deviceService.updateDevice(device);
|
||||
// cmder.deviceInfoQuery(device);
|
||||
}
|
||||
WVPResult<String> result = new WVPResult<>();
|
||||
result.setCode(0);
|
||||
|
@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.vmanager.log;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.service.ILogService;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.LogDto;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import io.swagger.annotations.Api;
|
||||
@ -18,7 +19,6 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
@Api(tags = "日志管理")
|
||||
@CrossOrigin
|
||||
@ -34,8 +34,6 @@ public class LogController {
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
/**
|
||||
* 分页查询日志
|
||||
*
|
||||
@ -80,10 +78,10 @@ public class LogController {
|
||||
|
||||
try {
|
||||
if (startTime != null) {
|
||||
format.parse(startTime);
|
||||
DateUtil.format.parse(startTime);
|
||||
}
|
||||
if (endTime != null) {
|
||||
format.parse(endTime);
|
||||
DateUtil.format.parse(endTime);
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
|
||||
|
@ -2,9 +2,8 @@ package com.genersoft.iot.vmp.vmanager.user;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.security.SecurityUtils;
|
||||
import com.genersoft.iot.vmp.service.IRoleService;
|
||||
import com.genersoft.iot.vmp.service.IUserService;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.Role;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.User;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
@ -13,12 +12,8 @@ import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "角色管理")
|
||||
@ -30,8 +25,6 @@ public class RoleController {
|
||||
@Autowired
|
||||
private IRoleService roleService;
|
||||
|
||||
private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@ApiOperation("添加角色")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "name", required = true, value = "角色名", dataTypeClass = String.class),
|
||||
@ -53,8 +46,8 @@ public class RoleController {
|
||||
Role role = new Role();
|
||||
role.setName(name);
|
||||
role.setAuthority(authority);
|
||||
role.setCreateTime(format.format(System.currentTimeMillis()));
|
||||
role.setUpdateTime(format.format(System.currentTimeMillis()));
|
||||
role.setCreateTime(DateUtil.getNow());
|
||||
role.setUpdateTime(DateUtil.getNow());
|
||||
|
||||
int addResult = roleService.add(role);
|
||||
|
||||
|
@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.service.IRoleService;
|
||||
import com.genersoft.iot.vmp.service.IUserService;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.Role;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.User;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
@ -20,7 +21,6 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.security.sasl.AuthenticationException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "用户管理")
|
||||
@ -38,8 +38,6 @@ public class UserController {
|
||||
@Autowired
|
||||
private IRoleService roleService;
|
||||
|
||||
private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@ApiOperation("登录")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "username", required = true, value = "用户名", dataTypeClass = String.class),
|
||||
@ -135,8 +133,8 @@ public class UserController {
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
user.setRole(role);
|
||||
user.setCreateTime(format.format(System.currentTimeMillis()));
|
||||
user.setUpdateTime(format.format(System.currentTimeMillis()));
|
||||
user.setCreateTime(DateUtil.getNow());
|
||||
user.setUpdateTime(DateUtil.getNow());
|
||||
int addResult = userService.addUser(user);
|
||||
|
||||
result.setCode(addResult > 0 ? 0 : -1);
|
||||
|
@ -2,12 +2,12 @@ package com.genersoft.iot.vmp.service.impl;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
||||
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
@ -18,8 +18,6 @@ class DeviceAlarmServiceImplTest {
|
||||
@Resource
|
||||
private IDeviceAlarmService deviceAlarmService;
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@org.junit.jupiter.api.Test
|
||||
void getAllAlarm() {
|
||||
// deviceAlarmService.getAllAlarm(0, 10000, "11111111111111111111",null,null,null, null, null);
|
||||
@ -67,7 +65,7 @@ class DeviceAlarmServiceImplTest {
|
||||
*/
|
||||
deviceAlarm.setAlarmMethod((int)(Math.random()*7 + 1) + "");
|
||||
Date date = randomDate("2021-01-01 00:00:00", "2021-06-01 00:00:00");
|
||||
deviceAlarm.setAlarmTime(format.format(date));
|
||||
deviceAlarm.setAlarmTime(DateUtil.format.format(date));
|
||||
/**
|
||||
* 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级 警情-
|
||||
*/
|
||||
@ -90,8 +88,8 @@ class DeviceAlarmServiceImplTest {
|
||||
private Date randomDate(String beginDate, String endDate) {
|
||||
try {
|
||||
|
||||
Date start = format.parse(beginDate);//构造开始日期
|
||||
Date end = format.parse(endDate);//构造结束日期
|
||||
Date start = DateUtil.format.parse(beginDate);//构造开始日期
|
||||
Date end = DateUtil.format.parse(endDate);//构造结束日期
|
||||
//getTime()表示返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
|
||||
if (start.getTime() >= end.getTime()) {
|
||||
return null;
|
||||
|
@ -4,12 +4,12 @@ import com.genersoft.iot.vmp.service.IRoleService;
|
||||
import com.genersoft.iot.vmp.service.IUserService;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.Role;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.User;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@ -20,7 +20,6 @@ class RoleServiceImplTest {
|
||||
@Resource
|
||||
private IRoleService roleService;
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
@org.junit.jupiter.api.Test
|
||||
void getAllUser() {
|
||||
List<Role> all = roleService.getAll();
|
||||
@ -35,8 +34,8 @@ class RoleServiceImplTest {
|
||||
Role role = new Role();
|
||||
role.setName("test+" + i);
|
||||
role.setAuthority("adadadda");
|
||||
role.setCreateTime(format.format(System.currentTimeMillis()));
|
||||
role.setUpdateTime(format.format(System.currentTimeMillis()));
|
||||
role.setCreateTime(DateUtil.getNow());
|
||||
role.setUpdateTime(DateUtil.getNow());
|
||||
roleService.add(role);
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,14 @@
|
||||
package com.genersoft.iot.vmp.service.impl;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
||||
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
||||
import com.genersoft.iot.vmp.service.IUserService;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.Role;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.User;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@ -22,7 +19,6 @@ class UserServiceImplTest {
|
||||
@Resource
|
||||
private IUserService userService;
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@org.junit.jupiter.api.Test
|
||||
void getAllUser() {
|
||||
@ -42,8 +38,8 @@ class UserServiceImplTest {
|
||||
Role role = new Role();
|
||||
role.setId(1);
|
||||
user.setRole(role);
|
||||
user.setCreateTime(format.format(System.currentTimeMillis()));
|
||||
user.setUpdateTime(format.format(System.currentTimeMillis()));
|
||||
user.setCreateTime(DateUtil.getNow());
|
||||
user.setUpdateTime(DateUtil.getNow());
|
||||
userService.addUser(user);
|
||||
}
|
||||
}
|
||||
@ -62,7 +58,7 @@ class UserServiceImplTest {
|
||||
Role role = new Role();
|
||||
role.setId(2);
|
||||
user.setRole(role);
|
||||
user.setUpdateTime(format.format(System.currentTimeMillis()));
|
||||
user.setUpdateTime(DateUtil.getNow());
|
||||
userService.updateUsers(user);
|
||||
}
|
||||
|
||||
|
@ -237,10 +237,10 @@ export default {
|
||||
that.initData();
|
||||
}, 1000)
|
||||
|
||||
} else {
|
||||
that.$message.error(res.data.msg);
|
||||
}
|
||||
}).catch(function (e) {
|
||||
that.isLoging = false;
|
||||
that.$message.error("请求超时");
|
||||
});
|
||||
},
|
||||
queryRecords: function (itemData) {
|
||||
|
Loading…
Reference in New Issue
Block a user