| | |
| | | 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";
|
| | |
|
| | |
| | | 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; |
| | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.text.SimpleDateFormat; |
| | | |
| | | /** |
| | | * @author lin |
| | |
| | | |
| | | 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; |
| | |
| | | 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()), |
| | |
| | | * 循环执行的任务 |
| | | * @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); |
| | | } |
| | | } |
| | | |
| | |
| | | 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; |
| | | } |
| | | } |
| | |
| | | if (future != null){ |
| | | futureMap.put(key, future); |
| | | runnableMap.put(key, task); |
| | | logger.info("任务【{}】启动成功!!!", key); |
| | | logger.debug("任务【{}】启动成功!!!", key); |
| | | }else { |
| | | logger.info("任务【{}】启动失败!!!", key); |
| | | logger.debug("任务【{}】启动失败!!!", key); |
| | | } |
| | | } |
| | | |
| | |
| | | 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{ |
| | |
| | | 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; |
| | | } |
| | |
| | | * 允许线程空闲时间(单位:默认为秒) |
| | | */ |
| | | private static final int keepAliveTime = 30; |
| | | |
| | | /** |
| | | * 缓冲队列大小 |
| | | */ |
| | | private static final int queueCapacity = 500; |
| | | private static final int queueCapacity = 10000; |
| | | /** |
| | | * 线程池名前缀 |
| | | */ |
| | |
| | | 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
|
| | |
| | | private String mediaServerId; |
| | | |
| | | /** |
| | | * 首次注册 |
| | | */ |
| | | private boolean firsRegister; |
| | | |
| | | /** |
| | | * 字符集, 支持 UTF-8 与 GB2312 |
| | | */ |
| | | private String charset ; |
| | |
| | | |
| | | public void setMediaServerId(String mediaServerId) { |
| | | this.mediaServerId = mediaServerId; |
| | | } |
| | | |
| | | public boolean isFirsRegister() { |
| | | return firsRegister; |
| | | } |
| | | |
| | | public void setFirsRegister(boolean firsRegister) { |
| | | this.firsRegister = firsRegister; |
| | | } |
| | | |
| | | public String getCharset() { |
| | |
| | | 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;
|
| | |
|
| | | /**
|
| | |
| | |
|
| | | @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 {
|
| | |
| | | // 添加任务处理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); |
| | | // 添加任务处理订阅过期 |
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
| | |
|
| | | @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);
|
| | | }
|
| | |
|
| | | /**
|
| | | * 平台心跳到期事件
|
| | |
| | | }
|
| | |
|
| | |
|
| | | public void requestTimeOut(TimeoutEvent timeoutEvent) {
|
| | | RequestTimeoutEvent requestTimeoutEvent = new RequestTimeoutEvent(this);
|
| | | requestTimeoutEvent.setTimeoutEvent(timeoutEvent);
|
| | | applicationEventPublisher.publishEvent(requestTimeoutEvent);
|
| | | }
|
| | |
|
| | |
|
| | | /**
|
| | | *
|
| | | * @param platformId
|
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | 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 { |
| | |
| | | // 平台心跳到期,需要重发, 判断是否已经多次未收到心跳回复, 多次未收到,则重新发起注册, 注册尝试多次未得到回复,则认为平台离线 |
| | | 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()); |
| | |
| | | sipSubscribe.getErrorSubscribe(callId).response(eventResult); |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.gb28181.task; |
| | | |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.service.IDeviceService; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | 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) |
| | | public class SipDeviceRunner implements CommandLineRunner { |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorage storager; |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | | |
| | | @Autowired |
| | | private IDeviceService deviceService; |
| | | |
| | | @Override |
| | | public void run(String... args) throws Exception { |
| | | List<Device> deviceList = deviceService.getAllOnlineDevice(); |
| | | |
| | | for (Device device : deviceList) { |
| | | if (deviceService.expire(device)){ |
| | | deviceService.offline(device.getDeviceId()); |
| | | }else { |
| | | deviceService.online(device); |
| | | } |
| | | } |
| | | // 重置cseq计数 |
| | | redisCatchStorage.resetAllCSEQ(); |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | 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; |
| | | |
| | | /** |
| | |
| | | @Autowired |
| | | private SipSubscribe sipSubscribe; |
| | | |
| | | @Autowired |
| | | private EventPublisher eventPublisher; |
| | | |
| | | // @Autowired |
| | | // @Qualifier(value = "taskExecutor") |
| | | // private ThreadPoolTaskExecutor poolTaskExecutor; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 添加 request订阅 |
| | |
| | | */ |
| | | @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 |
| | | public void processIOException(IOExceptionEvent exceptionEvent) { |
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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; |
| | | |
| | |
| | | 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) { |
| | |
| | | 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; |
| | |
| | | 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); |
| | |
| | | // 转发变化信息 |
| | | eventPublisher.catalogEventPublish(null, channel, eventElement.getText().toUpperCase()); |
| | | |
| | | } |
| | | |
| | | if (!redisCatchStorage.deviceIsOnline(deviceId)) { |
| | | publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_MESSAGE); |
| | | } |
| | | } |
| | | } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { |
| | |
| | | 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; |
| | |
| | | @Autowired |
| | | private SIPProcessorObserver sipProcessorObserver; |
| | | |
| | | @Autowired |
| | | private IDeviceService deviceService; |
| | | |
| | | @Override |
| | | public void afterPropertiesSet() throws Exception { |
| | | // 添加消息处理的订阅 |
| | |
| | | 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(); |
| | |
| | | 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头 |
| | |
| | | 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(); |
| | |
| | | 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(); |
| | |
| | | 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; |
| | |
| | | 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 { |
| | |
| | | |
| | | @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); |
| | | }else { |
| | | // 对于已经离线的设备判断他的注册是否已经过期 |
| | | if (!deviceService.expire(device)){ |
| | | device.setKeepaliveTime(DateUtil.getNow()); |
| | | // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息 |
| | | // 获取到通信地址等信息 |
| | | ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME); |
| | |
| | | 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); |
| | | deviceService.online(device); |
| | | // 回复200 OK |
| | | responseAck(evt, Response.OK); |
| | | } |
| | | } |
| | | } catch (SipException e) { |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | |
| | | 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; |
| | |
| | | |
| | | import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; |
| | | |
| | | /** |
| | | * @author lin |
| | | */ |
| | | @Component |
| | | public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { |
| | | |
| | |
| | | @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"); |
| | |
| | | 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) { |
| | |
| | | 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; |
| | |
| | | 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 { |
| | |
| | | @Autowired |
| | | private ResponseMessageHandler responseMessageHandler; |
| | | |
| | | |
| | | @Autowired |
| | | private DeferredResultHolder deferredResultHolder; |
| | | |
| | | @Autowired |
| | | private EventPublisher publisher; |
| | | private IDeviceService deviceService; |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | |
| | | public void handForDevice(RequestEvent evt, Device device, Element element) { |
| | | logger.info("接收到DeviceStatus应答消息"); |
| | | // 检查设备是否存在, 不存在则不回复 |
| | | if (device == null) { |
| | | return; |
| | | } |
| | | // 回复200 OK |
| | | try { |
| | | responseAck(evt, Response.OK); |
| | |
| | | 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 |
| | |
| | | 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; |
| | |
| | | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | @Autowired |
| | | private DynamicTask dynamicTask; |
| | | |
| | | @Qualifier("taskExecutor") |
| | | @Autowired |
| | | private ThreadPoolTaskExecutor taskExecutor; |
| | | |
| | | @Override |
| | | public void run(String... strings) throws Exception { |
| | |
| | | startGetMedia = new HashMap<>(); |
| | | } |
| | | startGetMedia.put(mediaServerItem.getId(), true); |
| | | taskExecutor.execute(()->{ |
| | | connectZlmServer(mediaServerItem); |
| | | }); |
| | | } |
| | | String taskKey = "zlm-connect-timeout"; |
| | | dynamicTask.startDelay(taskKey, ()->{ |
| | |
| | | startGetMedia = null; |
| | | } |
| | | // TODO 清理数据库中与redis不匹配的zlm |
| | | }, 6 * 1000 ); |
| | | }, 60 * 1000 ); |
| | | } |
| | | |
| | | @Async |
| | | public void connectZlmServer(MediaServerItem mediaServerItem){ |
| | | ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem, 1); |
| | | 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(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; |
| | |
| | | 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()); |
| | | // } |
| | | // } |
| | | // } |
| | | } |
| | |
| | | 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: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源: |
| | |
| | | @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()); |
| | | |
| | |
| | | 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); |
| | | } |
| | |
| | | |
| | | 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.stereotype.Service; |
| | | |
| | | import javax.sip.DialogState; |
| | | import javax.sip.TimeoutEvent; |
| | | import java.text.ParseException; |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 设备业务(目录订阅) |
| | |
| | | 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; |
| | |
| | | @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()); |
| | | device.setCreateTime(now); |
| | | } |
| | | device.setOnline(1); |
| | | device.setRegisterTime(now); |
| | | |
| | | // 第一次上线 |
| | | if (device.getCreateTime() == null) { |
| | | 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) { |
| | |
| | | // 提前开始刷新订阅 |
| | | 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; |
| | | } |
| | | |
| | |
| | | // 设置最小值为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; |
| | | } |
| | | |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | |
| | | @Autowired |
| | | JedisUtil jedisUtil; |
| | | |
| | | private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | /** |
| | | * 初始化 |
| | |
| | | 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(); |
| | | } |
| | |
| | | @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) { |
| | |
| | | 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; |
| | |
| | | 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 { |
| | |
| | | |
| | | @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) { |
| | |
| | | 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); |
| | |
| | | void clearCatchByDeviceId(String deviceId); |
| | | |
| | | /** |
| | | * 获取mediaServer节点 |
| | | * @param mediaServerId |
| | | * @return |
| | | */ |
| | | // MediaServerItem getMediaInfo(String mediaServerId); |
| | | |
| | | /** |
| | | * 设置所有设备离线 |
| | | */ |
| | | void outlineForAll(); |
| | | |
| | | /** |
| | | * 获取所有在线的 |
| | | */ |
| | | List<String> getOnlineForAll(); |
| | | |
| | | /** |
| | | * 在redis添加wvp的信息 |
| | | */ |
| | | void updateWVPInfo(JSONObject jsonObject, int time); |
| | |
| | | |
| | | @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); |
| | | } |
| | |
| | | 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") |
| | |
| | | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | | |
| | | private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @Override |
| | | public Long getCSEQ(String method) { |
| | |
| | | } |
| | | |
| | | @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(); |
| | | redis.set(key, jsonObject, time); |
| | |
| | | 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个 |
| | |
| | | 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个 |
| | |
| | | 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个 |
| | |
| | | |
| | | @Override |
| | | public boolean deviceIsOnline(String deviceId) { |
| | | String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetting.getServerId() + "_" + deviceId; |
| | | return redis.hasKey(key); |
| | | return getDevice(deviceId).getOnline() == 1; |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | | /** |
| | |
| | | @Autowired |
| | | private ParentPlatformMapper parentPlatformMapper; |
| | | |
| | | private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | |
| | | /** |
| | | * 根据设备ID判断设备是否存在 |
| | | * |
| | |
| | | */ |
| | | @Override |
| | | public synchronized boolean updateDevice(Device device) { |
| | | String now = this.format.format(System.currentTimeMillis()); |
| | | String now = DateUtil.getNow(); |
| | | device.setUpdateTime(now); |
| | | Device deviceByDeviceId = deviceMapper.getDeviceByDeviceId(device.getDeviceId()); |
| | | device.setCharset(device.getCharset().toUpperCase()); |
| | |
| | | |
| | | return deviceMapper.update(device) > 0; |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | @Override |
| | |
| | | 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) { |
| | |
| | | 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); |
| | |
| | | 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); |
| | |
| | | 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 { |
New file |
| | |
| | | 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()); |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | 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 = "报警信息管理") |
| | |
| | | |
| | | @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"); |
| | | |
| | | /** |
| | | * 分页查询报警 |
| | |
| | | |
| | | 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); |
| | |
| | | } |
| | | try { |
| | | if (time != null) { |
| | | format.parse(time); |
| | | DateUtil.format.parse(time); |
| | | } |
| | | } catch (ParseException e) { |
| | | return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); |
| | |
| | | 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); |
| | |
| | | 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; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | |
| | | @Api(tags = "日志管理") |
| | | @CrossOrigin |
| | |
| | | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | | |
| | | private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | /** |
| | | * 分页查询日志 |
| | |
| | | |
| | | 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); |
| | |
| | | |
| | | 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; |
| | |
| | | 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 = "角色管理") |
| | |
| | | |
| | | @Autowired |
| | | private IRoleService roleService; |
| | | |
| | | private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @ApiOperation("添加角色") |
| | | @ApiImplicitParams({ |
| | |
| | | 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); |
| | | |
| | |
| | | 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; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.security.sasl.AuthenticationException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.List; |
| | | |
| | | @Api(tags = "用户管理") |
| | |
| | | |
| | | @Autowired |
| | | private IRoleService roleService; |
| | | |
| | | private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @ApiOperation("登录") |
| | | @ApiImplicitParams({ |
| | |
| | | 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); |
| | |
| | | |
| | | 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; |
| | | |
| | | |
| | |
| | | |
| | | @Resource |
| | | private IDeviceAlarmService deviceAlarmService; |
| | | |
| | | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @org.junit.jupiter.api.Test |
| | | void getAllAlarm() { |
| | |
| | | */ |
| | | 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为四级 警情- |
| | | */ |
| | |
| | | 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; |
| | |
| | | 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; |
| | | |
| | | |
| | |
| | | @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(); |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | 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; |
| | | |
| | | |
| | |
| | | @Resource |
| | | private IUserService userService; |
| | | |
| | | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @org.junit.jupiter.api.Test |
| | | void getAllUser() { |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | Role role = new Role(); |
| | | role.setId(2); |
| | | user.setRole(role); |
| | | user.setUpdateTime(format.format(System.currentTimeMillis())); |
| | | user.setUpdateTime(DateUtil.getNow()); |
| | | userService.updateUsers(user); |
| | | } |
| | | |
| | |
| | | that.initData(); |
| | | }, 1000) |
| | | |
| | | } else { |
| | | that.$message.error(res.data.msg); |
| | | } |
| | | }).catch(function (e) { |
| | | that.isLoging = false; |
| | | that.$message.error("请求超时"); |
| | | }); |
| | | }, |
| | | queryRecords: function (itemData) { |