648540858
2023-05-04 381c3bdc2079ece5147cf4cee004e9071edadf7a
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
@@ -1,34 +1,33 @@
package com.genersoft.iot.vmp.service.impl;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
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.gb28181.utils.Coordtransform;
import com.genersoft.iot.vmp.service.IDeviceChannelService;
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.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler;
import com.genersoft.iot.vmp.service.IDeviceChannelService;
import com.genersoft.iot.vmp.service.IDeviceService;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
import com.genersoft.iot.vmp.storager.dao.PlatformChannelMapper;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.BaseTree;
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.support.incrementer.AbstractIdentityColumnMaxValueIncrementer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
@@ -46,8 +45,6 @@
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;
@@ -80,7 +77,7 @@
    TransactionDefinition transactionDefinition;
    @Autowired
    private IVideoManagerStorage storage;
    private UserSetting userSetting;
    @Autowired
    private ISIPCommander commander;
@@ -92,7 +89,7 @@
    private IMediaServerService mediaServerService;
    @Override
    public void online(Device device) {
    public void online(Device device, SipTransactionInfo sipTransactionInfo) {
        logger.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort());
        Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId());
        Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
@@ -103,6 +100,17 @@
            redisCatchStorage.clearCatchByDeviceId(device.getDeviceId());
        }
        device.setUpdateTime(now);
        if (device.getKeepaliveIntervalTime() == 0) {
            // 默认心跳间隔60
            device.setKeepaliveIntervalTime(60);
        }
        if (sipTransactionInfo != null) {
            device.setSipTransactionInfo(sipTransactionInfo);
        }else {
            if (deviceInRedis != null) {
                device.setSipTransactionInfo(deviceInRedis.getSipTransactionInfo());
            }
        }
        // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询
        if (device.getCreateTime() == null) {
@@ -121,17 +129,24 @@
            if(device.getOnline() == 0){
                device.setOnline(1);
                device.setCreateTime(now);
                logger.info("[设备上线,离线状态下重新注册]: {},查询设备信息以及通道信息", device.getDeviceId());
                deviceMapper.update(device);
                redisCatchStorage.updateDevice(device);
                try {
                    commander.deviceInfoQuery(device);
                } catch (InvalidArgumentException | SipException | ParseException e) {
                    logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage());
                if (userSetting.getSyncChannelOnDeviceOnline()) {
                    logger.info("[设备上线,离线状态下重新注册]: {},查询设备信息以及通道信息", device.getDeviceId());
                    try {
                        commander.deviceInfoQuery(device);
                    } catch (InvalidArgumentException | SipException | ParseException e) {
                        logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage());
                    }
                    sync(device);
                    // TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台
                }
                sync(device);
                // TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台
            }else {
                if (deviceChannelMapper.queryAllChannels(device.getDeviceId()).size() == 0) {
                    logger.info("[设备上线]: {},通道数为0,查询通道信息", device.getDeviceId());
                    sync(device);
                }
                deviceMapper.update(device);
                redisCatchStorage.updateDevice(device);
            }
@@ -147,24 +162,30 @@
            addMobilePositionSubscribe(device);
        }
        // 刷新过期任务
        String registerExpireTaskKey = registerExpireTaskKeyPrefix + device.getDeviceId();
        dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), device.getExpires() * 1000);
        String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
        // 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
        dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "首次注册后未能收到心跳"), device.getKeepaliveIntervalTime() * 1000 * 3);
        if (userSetting.getDeviceStatusNotify()) {
            // 发送redis消息
            redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, true);
        }
    }
    @Override
    public void offline(String deviceId) {
        logger.info("[设备离线], device:{}", deviceId);
    public void offline(String deviceId, String reason) {
        logger.error("[设备离线],{}, device:{}", reason, deviceId);
        Device device = deviceMapper.getDeviceByDeviceId(deviceId);
        if (device == null) {
            return;
        }
        String registerExpireTaskKey = registerExpireTaskKeyPrefix + deviceId;
        String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + deviceId;
        dynamicTask.stop(registerExpireTaskKey);
        device.setOnline(0);
        redisCatchStorage.updateDevice(device);
        deviceMapper.update(device);
        //进行通道离线
        deviceChannelMapper.offlineByDeviceId(deviceId);
//        deviceChannelMapper.offlineByDeviceId(deviceId);
        // 离线释放所有ssrc
        List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(deviceId, null, null, null);
        if (ssrcTransactions != null && ssrcTransactions.size() > 0) {
@@ -177,6 +198,11 @@
        // 移除订阅
        removeCatalogSubscribe(device);
        removeMobilePositionSubscribe(device);
        if (userSetting.getDeviceStatusNotify()) {
            // 发送redis消息
            redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, false);
        }
    }
    @Override
@@ -326,7 +352,6 @@
        device.setUpdateTime(DateUtil.getNow());
        if (deviceMapper.update(device) > 0) {
            redisCatchStorage.updateDevice(device);
        }
    }
@@ -402,7 +427,7 @@
            if (parentId.length() < 14 ) {
                return null;
            }
            List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null);
            List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);
            List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(deviceChannels, parentId);
            return trees;
        }
@@ -447,7 +472,7 @@
            if (parentId.length() < 14 ) {
                return null;
            }
            List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null);
            List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);
            return deviceChannels;
        }
@@ -511,7 +536,7 @@
                }
            }else {
                if (haveChannel) {
                    List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null);
                    List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null,null);
                    if (deviceChannels != null && deviceChannels.size() > 0) {
                        result.addAll(deviceChannels);
                    }
@@ -559,6 +584,9 @@
        if (!ObjectUtils.isEmpty(device.getMediaServerId())) {
            deviceInStore.setMediaServerId(device.getMediaServerId());
        }
        deviceInStore.setSdpIp(device.getSdpIp());
        deviceInStore.setCharset(device.getCharset());
        deviceInStore.setTreeType(device.getTreeType());
        //  目录订阅相关的信息
        if (device.getSubscribeCycleForCatalog() > 0) {
@@ -593,6 +621,8 @@
        if (!deviceInStore.getGeoCoordSys().equals(device.getGeoCoordSys())) {
            updateDeviceChannelGeoCoordSys(device);
        }
        // 更新redis
        redisCatchStorage.updateDevice(device);
        deviceMapper.updateCustom(device);
    }
@@ -614,4 +644,16 @@
        }
        return result;
    }
    @Override
    public ResourceBaceInfo getOverview() {
        return deviceMapper.getOverview();
    }
    @Override
    public List<Device> getAll() {
        return deviceMapper.getAll();
    }
}