视图库对接系列(GA-T 1400)四、视图库对接系列(本级)注册

视图库对接系列(本级)注册

在之前的步骤中,我们已经把项目大体的架构已经写出来了。那我们就来实现注册接口。

GA-T 1400中的步骤如下:

在这里插入图片描述
这里的话,我们实现的简单点, 我们不进去鉴权,也就是设备或平台找我们注册的话,我们直接返回成功,不进行验证。
如果需要鉴权的话可看我的另外一篇文档。
视图库对接系列(GA-T 1400)七、视图库对接系列(本级)注册(包含鉴权)

注册前准备

因为视图库对接 主要是解析、验证解析。 所以我们先暂时把对应的文件创建好,这里的话我就直接先放截图,到时候有需要的直接加群拿,我把项目放在群里把。
在这里插入图片描述

注册

service层

我把注册、注销、保活、校时的接口一起写好,后续我们直接实现就可以了。

在common中添加ViewLibCommonRequestService

public interface ViewLibCommonRequestService {

    //注册
    ResponseStatusObject register(DeviceViewBaseParam param);


    //注销
    ResponseStatusObject unregister(DeviceViewBaseParam param);

    //保活
    ResponseStatusObject keepalive(DeviceViewBaseParam param);

    //校时
    ResponseStatusObject time(DeviceViewBaseParam param);
}

在server中添加PlatformService继承ViewLibCommonRequestService就可以了

public interface PlatformService extends ViewLibCommonRequestService {
}

service层实现

@Service
public class PlatformServiceImpl implements PlatformService, TaskService {

    @Resource
    private IViewLibraryDomainDeviceService viewLibraryDomainDeviceService;

    /**
     * 心跳key
     */
    public static final String TASK_CASCADE_KEEP_KEY = "platform_keep_alive";

    /**
     * 默认心跳周期
     */
    public static final Integer DEFAULT_HEARTBEAT_CYCLE = 3;
    /**
     * 默认最大心跳超时时间
     */
    public static final Integer DEFAULT_MAX_HEARTBEAT_TIMEOUT_NUM = 60;

    @Override
    public ResponseStatusObject register(DeviceViewBaseParam param, String url) {
        int heartbeatCycle = DEFAULT_HEARTBEAT_CYCLE;
        int maxHeartbeatTimeoutNum = DEFAULT_MAX_HEARTBEAT_TIMEOUT_NUM;
        // 保存到domain_platform 中 设备id,状态(注册默认在线,保活时间取最新时间)
        ViewLibraryDomainDevice domainPlatform = viewLibraryDomainDeviceService.selectByDomainDeviceId(param.getDeviceId());
        if (domainPlatform == null) {
            viewLibraryDomainDeviceService.save(new ViewLibraryDomainDevice(param.getDeviceId(), PlatformStatus.ONLINE.getValue(), LocalDateTime.now(), DEFAULT_HEARTBEAT_CYCLE, DEFAULT_MAX_HEARTBEAT_TIMEOUT_NUM));
        } else {
            viewLibraryDomainDeviceService.updateRegisterStatus(param.getDeviceId(), PlatformStatus.ONLINE.getValue());
            heartbeatCycle = domainPlatform.getHeartbeatCycle();
            maxHeartbeatTimeoutNum = domainPlatform.getMaxHeartbeatTimeoutNum();
        }
        ScheduleUtil.start(
                new ScheduleTask(TASK_CASCADE_KEEP_KEY + param.getDeviceId(), this, ""),
                new Date(System.currentTimeMillis() + heartbeatCycle * maxHeartbeatTimeoutNum * 1000 * 1000)
        );
        return ResponseStatusObject.initSuccess(url, param, "注册成功");
    }

    @Override
    public ResponseStatusObject unregister(DeviceViewBaseParam param, String url) {
        return null;
    }

    @Override
    public ResponseStatusObject keepalive(DeviceViewBaseParam param, String url) {
        return null;
    }

    @Override
    public ResponseStatusObject time(DeviceViewBaseParam param, String url) {
        return null;
    }

    @Override
    public void work(String id, String keyword) {
        String platformId = id.replace(TASK_CASCADE_KEEP_KEY, "");
        ViewLibraryDomainDevice viewLibraryDomainPlatform = viewLibraryDomainDeviceService.selectByDomainDeviceId(platformId);
        if (viewLibraryDomainPlatform != null) {
            LocalDateTime latestKeepAliveTime = viewLibraryDomainPlatform.getLatestKeepAliveTime();
            if (latestKeepAliveTime == null) {
                viewLibraryDomainDeviceService.updateRegisterStatus(viewLibraryDomainPlatform.getDeviceId(), PlatformStatus.LOGGED_OUT.getValue());
                return;
            }
            if (DateUtil.isAfterAddingSeconds(LocalDateTime.now(), latestKeepAliveTime, viewLibraryDomainPlatform.getMaxHeartbeatTimeoutNum() * viewLibraryDomainPlatform.getHeartbeatCycle())) {
                viewLibraryDomainDeviceService.updateRegisterStatus(viewLibraryDomainPlatform.getDeviceId(), PlatformStatus.LOGGED_OUT.getValue());
            }


        }
    }

这里有个TaskService实现, 我稍微说一下。 因为设备需要每隔一段时间给我们一个心跳,所以我们封装了一个定时器回调,回调方法是work。每隔多久对比一下时间,将状态进行更改。

设备层service

public interface IViewLibraryDomainDeviceService extends IService<ViewLibraryDomainDevice> {
    void updateRegisterStatus(String deviceId,Integer status);

    ViewLibraryDomainDevice selectByDomainDeviceId(String deviceId);
}

设备层service实现

@Service
public class ViewLibraryDomainDeviceServiceImpl extends ServiceImpl<ViewLibraryDomainDeviceMapper, ViewLibraryDomainDevice> implements IViewLibraryDomainDeviceService {

    @Override
    public void updateRegisterStatus(String deviceId, Integer status) {
        LambdaUpdateWrapper<ViewLibraryDomainDevice> queryWrapper = Wrappers.lambdaUpdate();
        queryWrapper.eq(ViewLibraryDomainDevice::getDeviceId,deviceId);
        ViewLibraryDomainDevice domainPlatform = new ViewLibraryDomainDevice();
        domainPlatform.setDeviceStatus(status);
        domainPlatform.setLatestKeepAliveTime(LocalDateTime.now());
        this.baseMapper.update(domainPlatform,queryWrapper);
    }

    @Override
    public ViewLibraryDomainDevice selectByDomainDeviceId(String deviceId) {
        LambdaQueryWrapper<ViewLibraryDomainDevice> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ViewLibraryDomainDevice::getDeviceId, deviceId);
        return  this.baseMapper.selectOne(queryWrapper);
    }
}

##Controller层

@RestController
@CrossOrigin(value = "*", maxAge = 3600)
@RequestMapping("/VIID")
@RequestLog(logReturn = true)
public class PlatformController {
    

    @Resource
    private PlatformService platformService;

    //-------------------------------------------------设备或平台请求------------------------------------------

    @PostMapping("/System/Register")
    public ResponseStatusObject register(@RequestBody RegisterObjectRequest param, HttpServletRequest request, HttpServletResponse response) {
        String userIdentify = CommonUtlis.getUserIdentify(request);
        //{"RegisterObject":{"RequestURL":"/VIID/System/Register","StatusCode":0,"StatusString":"注册成功","Id":"33048300005030000237","LocalTime":"20220826085911"}}
        if(param == null || param.getDeviceBaseParam()== null || StringUtils.isEmpty(param.getDeviceBaseParam().getId())) {
            return ResponseStatusObject.initFailCode(request.getRequestURI(),userIdentify,String.valueOf( StatusCodeEnum.PLATFORM_PARAMETER_FAIL.getCode()));
        }
        return platformService.register(param.getDeviceBaseParam(),request.getRequestURI());

    }

    



}

这里的话我使用了自定义的注解来打日志
具体可以看我的这一章
java实现日志aop切面 和业务功能进行解耦

测试

我们在设备后台,配置好对应的参数,然后看抓包是否ok

设备配置

我们视图库的ip和端口,也就是我们目前写的server项目的ip和端口
在这里插入图片描述

抓包

本机抓包

如果是本机抓包的话 需要添加路由。

route add 你的ip mask 255.255.255.255 对应网卡

如: route add 192.168.6.16 mask 255.255.255.255 192.168.6.1
在这里插入图片描述

使用Wireshark抓包查看

抓包数据如下:

在这里插入图片描述

在这里插入图片描述

数据库数据也已成功 添加

在这里插入图片描述

视图库对接系列(本级)注册完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/768338.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VideoPrism——探索视频分析领域模型的算法与应用

概述 论文地址:https://arxiv.org/pdf/2402.13217.pdf 视频是我们观察世界的生动窗口&#xff0c;记录了从日常瞬间到科学探索的各种体验。在这个数字时代&#xff0c;视频基础模型&#xff08;ViFM&#xff09;有可能分析如此海量的信息并提取新的见解。迄今为止&#xff0c;…

Rustdesk如何编译代码实现安装后不会显示主界面,不会在右下角出现托盘图标,作为后台服务运行

环境&#xff1a; Rustdesk1.1.9 问题描述&#xff1a; Rustdesk如何编译代码实现安装后不会显示主界面&#xff0c;不会在右下角出现托盘图标&#xff0c;作为后台服务运行 解决方案&#xff1a; 可以自定义进程名称和图标&#xff0c;不会显示主界面&#xff0c;不会在…

小试牛刀-区块链代币锁仓(Web页面)

Welcome to Code Blocks blog 本篇文章主要介绍了 [区跨链代币锁仓(Web页面)] ❤博主广交技术好友&#xff0c;喜欢我的文章的可以关注一下❤ 目录 1.编写目的 2.开发环境 3.实现功能 4.代码实现 4.1 必要文件 4.1.1 ABI Json文件(LockerContractABI.json) 4.2 代码详解…

uniapp + vite中 uni.scss 使用 /deep/ 不生效(踩坑记录三)

vite 中使用 /deep/ 进行样式穿透报错 原因&#xff1a;vite 中不支持&#xff0c;换成 ::v-deep 或:deep即可

linux应用开发基础知识(八)——内存共享(mmap和system V)

mmap内存映射 内存共享定义 内存映射&#xff0c;简而言之就是将用户空间的一段内存区域映射到内核空间&#xff0c;映射成功后&#xff0c;用户对这段内存区域的修改可以直接反映到内核空间&#xff0c;同样&#xff0c;内核空间对这段区域的修改也直接反映用户空间。那么对…

在TkinterGUI界面显示WIFI网络摄像头(ESP32s3)视频画面

本实验结合了之前写过的两篇文章Python调用摄像头&#xff0c;实时显示视频在Tkinter界面以及ESP32 S3搭载OV2640摄像头释放热点&#xff08;AP&#xff09;工作模式–Arduino程序&#xff0c;当然如果手头有其他可以获得网络摄像头的URL即用于访问摄像头视频流的网络地址&…

如何快速掌握一门编程语言

学习一门新的编程语言可能是一个具有挑战性的过程&#xff0c;但通过一些系统的方法&#xff0c;可以大大加快这个过程。 目录 第一步&#xff1a;通过书籍和视频课程掌握基本语法1. **学习编程语言的基础知识**2. **掌握字符串处理**3. **掌握正则表达式和解析器**4. **掌握面…

停车场车牌识别计费系统,用Python如何实现?

关注星标&#xff0c;每天学习Python新技能 前段时间练习过的一个小项目&#xff0c;今天再看看&#xff0c;记录一下~ 项目结构 说明&#xff1a; datefile文件夹&#xff1a;保存车辆信息表的xlsx文件 file文件夹&#xff1a;保存图片文件夹。ic_launcher.jpg是窗体的右上角…

什么是 URL ?

统一资源定位符&#xff08;URL&#xff09;是一个字符串&#xff0c;它指定了一个资源在互联网上的位置以及如何访问它。URL 是由几部分组成的&#xff0c;每部分都有其特定的作用&#xff1a; 协议/方案&#xff1a;这是 URL 的开头部分&#xff0c;表明了用于访问资源的协议…

stm32F4库函数c++和C混合编程笔记20240626

1、有时候需要用到c的一些特性&#xff0c;封装&#xff0c;类等等。 2、研究一下如何更改之前c工程的内容&#xff0c;实现混合编程。 操作 1、keil设置 2、要重新建立一个main文件&#xff0c;后缀名是cpp&#xff0c;cpp才能调用cpp. 后面如果要用到c特性的&#xff0c;需要…

python sklearn机械学习-数据预处理

&#x1f308;所属专栏&#xff1a;【机械学习】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您…

C++: 左值引用和右值引用

目录 概念&#xff1a; 理解&#xff1a; 左值引用&#xff0c;右值引用 左值引用能否给右值取别名&#xff1f; 右值引用能否给左值取别名&#xff1f; 引用的意义是什么&#xff1f; 左值和右值对自定义类型有什么区别吗&#xff1f; move的妙用&#xff01; 没有优化…

统计信号处理基础 习题解答11-13

题目 如果是一个2x1的随机矢量&#xff0c;具有PDF 证明的PDF是一个随机变量。提可以因式分解成&#xff0c;其中是一个在4.5节描述的白化变换。 解答 首先&#xff1a; 因此&#xff0c;存在&#xff1a; 也就是是Hermitian矩阵。详细的性质可以参考&#xff1a; https://z…

Git使用[推送大于100M的文件后解救办法]

推送大于100M的文件后解救办法 本文摘录于&#xff1a;https://blog.csdn.net/u012150602/article/details/122687435只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 当有文件大于100M的时候在提交的时候没有问题,但是在push的似乎就不行…

电影院售票管理系统(小白)大佬求解

最近在写一个关于电影院售票管理系统的sm项目&#xff0c;但是在买票的环节出现了问题及点击选座购票&#xff0c;没有数据渲染出来&#xff0c;我不知道什么情况&#xff0c;所以问问。有没有大佬可以帮我解决这个问题&#xff1f;下面是我的。控制层&#xff0c;服务层&#…

学校考场电子钟除了报时,还能做什么?-讯鹏时钟

在学校考场中&#xff0c;电子钟的存在似乎已经司空见惯&#xff0c;大多数人仅仅将其视为报时的工具。然而&#xff0c;学校考场电子钟的作用远不止于此&#xff0c;它具备众多优势和丰富的功能。 学校考场电子钟能够提供精准的时间参考&#xff0c;这是其最基础也是最关键的功…

Qt:5.QWidget属性介绍(Enabled属性-控件可用性设置、geometry属性-控件位置/大小设置)

目录 一、 QWidget属性的介绍&#xff1a; 二、Enabled属性-控件可用性设置&#xff1a; 2.1Enabled属性的介绍&#xff1a; 2.2获取控件当前可用状态的api——isEnabled()&#xff1a; 2.3设置控件当前的可用状态的api—— setEnabled() &#xff1a; 2.4 实例&#xff…

第二十一章 网络编程

​ 一、网络的相关概念 1. 网络通信 &#xff08;1&#xff09;网络通信&#xff1a;将 数据 通过网络从一台设备传输到另一台设备 &#xff08;2&#xff09;java.net 包下提供了一系列的类或接口&#xff0c;完成网络通信 2. 网络 概念&#xff1a;两台或多台设备通过一定…

VideoLLaMA 2:多模态视频理解新突破,音频理解能力再升级,挑战 GPT-4V

前言 近年来&#xff0c;人工智能技术飞速发展&#xff0c;尤其是大模型的出现&#xff0c;为视频理解和生成领域带来了前所未有的机遇。然而&#xff0c;现有的视频大模型&#xff08;Video-LLM&#xff09;在处理视频中复杂的时空信息和音频信息方面仍存在不足&#xff0c;例…

基于矩阵分解算法的评分预测实现---信息检索课设以及所涉及的深度学习原理

一、实验环境 Windows,Python 3 Python作为主要编程语言,使用Python的Pandas、NumPy、Matplotlib等库 二、实验内容 主要任务 查阅相关资料,了解矩阵分解算法的基本概念、应用场景及其难点。重点了解SVD(Singular Value Decomposition,奇异值分解)系列方法。掌握Pyth…