| | |
| | | import com.ard.gb28181.task.deviceSubscribe.deviceSubscribe.SubscribeTaskRunner; |
| | | import com.ard.gb28181.task.deviceSubscribe.deviceSubscribe.impl.SubscribeTaskForCatalog; |
| | | import com.ard.gb28181.task.deviceSubscribe.deviceSubscribe.impl.SubscribeTaskForMobilPosition; |
| | | import com.ard.qs.api.RemoteQsDeviceService; |
| | | import com.ard.zlm.api.RemoteZlmService; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import javax.sip.InvalidArgumentException; |
| | | import javax.sip.SipException; |
| | |
| | | |
| | | @Autowired |
| | | private RemoteZlmService remoteZlmService; |
| | | |
| | | @Autowired |
| | | private RemoteQsDeviceService remoteQsDeviceService; |
| | | |
| | | @Autowired |
| | | private IGbDeviceService gbDeviceService; |
| | |
| | | DeviceStatusTask task = DeviceStatusTask.getInstance(device.getDeviceId(), sipTransactionInfo, expiresTime + System.currentTimeMillis(), this::deviceStatusExpire); |
| | | deviceStatusTaskRunner.addTask(task); |
| | | } |
| | | // 同步设备状态到 QS 模块 |
| | | try { |
| | | remoteQsDeviceService.updateDeviceStatusByGbDeviceId(device.getDeviceId(), "ON", SecurityConstants.INNER); |
| | | } catch (Exception e) { |
| | | log.error("[同步设备状态] 设备上线,同步到 QS 模块失败:{}", device.getDeviceId(), e); |
| | | } |
| | | |
| | | // 设备注册成功时,自动在 ard_gb_device 表中创建设备记录(若不存在) |
| | | try { |
| | | GbDevice existingDevice = gbDeviceService.selectGbDeviceByGbDeviceId(device.getDeviceId()); |
| | | if (existingDevice == null) { |
| | | GbDevice gbDevice = new GbDevice(); |
| | | gbDevice.setGbDeviceId(device.getDeviceId()); |
| | | gbDevice.setDeviceName(device.getName() != null ? device.getName() : device.getDeviceId()); |
| | | gbDevice.setDeviceName(StringUtils.hasText(device.getName()) ? device.getName() : device.getDeviceId()); |
| | | gbDevice.setDeviceCode(device.getDeviceId()); |
| | | gbDevice.setStreamMode(device.getStreamMode() != null ? device.getStreamMode() : "TCP-PASSIVE"); |
| | | gbDevice.setEnableMp4("0"); |
| | | gbDevice.setIp(device.getIp()); |
| | | gbDevice.setPort(device.getPort()); |
| | | gbDevice.setManufacturer(device.getManufacturer()); |
| | | gbDevice.setModel(device.getModel()); |
| | | gbDevice.setFirmware(device.getFirmware()); |
| | | gbDevice.setOnLine(true); |
| | | gbDeviceService.insertGbDevice(gbDevice); |
| | | log.info("[GbDevice自动创建] deviceId: {}, id: {}", device.getDeviceId(), gbDevice.getId()); |
| | | |
| | |
| | | GbChannel gbChannel = new GbChannel(); |
| | | gbChannel.setGbDeviceId(device.getDeviceId()); |
| | | gbChannel.setGbChannelId(device.getDeviceId()); |
| | | gbChannel.setChannelName(device.getName() != null ? device.getName() : device.getDeviceId()); |
| | | gbChannel.setChannelName(StringUtils.hasText(device.getName()) ? device.getName() : device.getDeviceId()); |
| | | gbChannel.setDeviceCode(device.getDeviceId()); |
| | | gbChannel.setStreamMode(device.getStreamMode() != null ? device.getStreamMode() : "TCP-PASSIVE"); |
| | | gbChannel.setEnableMp4("0"); |
| | | gbChannelService.insertGbChannel(gbChannel); |
| | | log.info("[GbChannel默认创建] deviceId: {}, channelId: {}, id: {}", |
| | | device.getDeviceId(), device.getDeviceId(), gbChannel.getId()); |
| | | } else { |
| | | // 设备已存在,更新最新信息(名称、IP、端口、厂商、型号、固件) |
| | | boolean needUpdate = false; |
| | | String newName = StringUtils.hasText(device.getName()) ? device.getName() : device.getDeviceId(); |
| | | if (!newName.equals(existingDevice.getDeviceName())) { |
| | | existingDevice.setDeviceName(newName); |
| | | needUpdate = true; |
| | | } |
| | | if (device.getIp() != null && !device.getIp().equals(existingDevice.getIp())) { |
| | | existingDevice.setIp(device.getIp()); |
| | | needUpdate = true; |
| | | } |
| | | if (device.getPort() > 0 && (existingDevice.getPort() == null || device.getPort() != existingDevice.getPort())) { |
| | | existingDevice.setPort(device.getPort()); |
| | | needUpdate = true; |
| | | } |
| | | if (device.getManufacturer() != null && !device.getManufacturer().equals(existingDevice.getManufacturer())) { |
| | | existingDevice.setManufacturer(device.getManufacturer()); |
| | | needUpdate = true; |
| | | } |
| | | if (device.getModel() != null && !device.getModel().equals(existingDevice.getModel())) { |
| | | existingDevice.setModel(device.getModel()); |
| | | needUpdate = true; |
| | | } |
| | | if (device.getFirmware() != null && !device.getFirmware().equals(existingDevice.getFirmware())) { |
| | | existingDevice.setFirmware(device.getFirmware()); |
| | | needUpdate = true; |
| | | } |
| | | if (existingDevice.getOnLine() == null || !existingDevice.getOnLine()) { |
| | | existingDevice.setOnLine(true); |
| | | needUpdate = true; |
| | | } |
| | | if (needUpdate) { |
| | | gbDeviceService.updateGbDevice(existingDevice); |
| | | log.info("[GbDevice更新] deviceId: {}, name={}, ip={}, port={}, manufacturer={}, model={}, firmware={}", |
| | | device.getDeviceId(), existingDevice.getDeviceName(), |
| | | existingDevice.getIp(), existingDevice.getPort(), |
| | | existingDevice.getManufacturer(), existingDevice.getModel(), existingDevice.getFirmware()); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("[GbDevice自动创建] 设备上线,自动创建失败:{}", device.getDeviceId(), e); |
| | |
| | | if (isDevice(deviceId)) { |
| | | channelOfflineByDevice(device); |
| | | } |
| | | // 同步设备状态到 QS 模块 |
| | | |
| | | // 同步更新 MySQL 在线状态 |
| | | try { |
| | | remoteQsDeviceService.updateDeviceStatusByGbDeviceId(deviceId, "OFFLINE", SecurityConstants.INNER); |
| | | GbDevice gbDevice = gbDeviceService.selectGbDeviceByGbDeviceId(deviceId); |
| | | if (gbDevice != null) { |
| | | gbDevice.setOnLine(false); |
| | | gbDeviceService.updateGbDevice(gbDevice); |
| | | log.info("[设备离线] 更新MySQL在线状态: {} -> offline", deviceId); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("[同步设备状态] 设备离线,同步到 QS 模块失败:{}", deviceId, e); |
| | | log.error("[设备离线] 更新MySQL在线状态失败: {}", deviceId, e); |
| | | } |
| | | |
| | | // 主动注销时:清理 Redis 中的通道数据,删除 MySQL 中该设备的通道记录 |
| | | if ("主动注销".equals(reason)) { |
| | | try { |
| | | redisCatchStorage.cleanChannelsForDevice(deviceId); |
| | | log.info("[设备离线] 主动注销,已清理Redis通道: {}", deviceId); |
| | | } catch (Exception e) { |
| | | log.error("[设备离线] 清理Redis通道失败: {}", deviceId, e); |
| | | } |
| | | try { |
| | | List<GbChannel> channels = gbChannelService.selectGbChannelByGbDeviceId(deviceId); |
| | | int deletedCount = 0; |
| | | int skippedCount = 0; |
| | | for (GbChannel ch : channels) { |
| | | // 跳过正在推流的通道,避免误删 |
| | | if ("1".equals(ch.getStreamStatus())) { |
| | | ch.setStreamStatus("0"); |
| | | gbChannelService.updateGbChannelStream(ch); |
| | | skippedCount++; |
| | | continue; |
| | | } |
| | | gbChannelService.deleteGbChannelById(ch.getId()); |
| | | deletedCount++; |
| | | } |
| | | log.info("[设备离线] 主动注销,已清理MySQL通道: {}条删除, {}条跳过", deletedCount, skippedCount); |
| | | } catch (Exception e) { |
| | | log.error("[设备离线] 清理MySQL通道失败: {}", deviceId, e); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * 获取所有国标设备 |
| | | * 获取所有国标设备(从数据库查询,Redis 补充在线状态等运行时信息) |
| | | * |
| | | * @return 设备列表 |
| | | */ |
| | | @Override |
| | | public List<Device> getAllDevices() { |
| | | List<Device> result = new java.util.ArrayList<>(); |
| | | List<GbDevice> gbDevices = gbDeviceService.selectGbDeviceList(new GbDevice()); |
| | | for (GbDevice gbDevice : gbDevices) { |
| | | // 从 Redis 获取运行时信息(在线状态、IP、端口等) |
| | | Device redisDevice = redisCatchStorage.getDevice(gbDevice.getGbDeviceId()); |
| | | if (redisDevice != null) { |
| | | // 用数据库的名称/厂商/型号覆盖 Redis 数据 |
| | | if (StringUtils.hasText(gbDevice.getDeviceName())) { |
| | | redisDevice.setName(gbDevice.getDeviceName()); |
| | | } |
| | | if (StringUtils.hasText(gbDevice.getManufacturer())) { |
| | | redisDevice.setManufacturer(gbDevice.getManufacturer()); |
| | | } |
| | | if (StringUtils.hasText(gbDevice.getModel())) { |
| | | redisDevice.setModel(gbDevice.getModel()); |
| | | } |
| | | if (StringUtils.hasText(gbDevice.getFirmware())) { |
| | | redisDevice.setFirmware(gbDevice.getFirmware()); |
| | | } |
| | | result.add(redisDevice); |
| | | } else { |
| | | // Redis 中没有(设备离线已久),用数据库数据构造基本 Device 对象 |
| | | Device device = new Device(); |
| | | device.setDeviceId(gbDevice.getGbDeviceId()); |
| | | device.setName(StringUtils.hasText(gbDevice.getDeviceName()) |
| | | ? gbDevice.getDeviceName() : gbDevice.getGbDeviceId()); |
| | | device.setOnLine(gbDevice.getOnLine() != null && gbDevice.getOnLine()); |
| | | device.setIp(gbDevice.getIp()); |
| | | device.setPort(gbDevice.getPort() != null ? gbDevice.getPort() : 0); |
| | | device.setManufacturer(gbDevice.getManufacturer()); |
| | | device.setPort(gbDevice.getPort() != null ? gbDevice.getPort() : 0); |
| | | device.setManufacturer(gbDevice.getManufacturer()); |
| | | device.setModel(gbDevice.getModel()); |
| | | device.setFirmware(gbDevice.getFirmware()); |
| | | result.add(device); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 获取所有国标设备(直接从 Redis 查询,用于迁移/同步等场景) |
| | | * |
| | | * @return 设备列表 |
| | | */ |
| | | @Override |
| | | public List<Device> getAllRedisDevices() { |
| | | return redisCatchStorage.getAllDevices(); |
| | | } |
| | | |