视图库对接系列(本级)注册
在之前的步骤中,我们已经把项目大体的架构已经写出来了。那我们就来实现注册接口。
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抓包查看
抓包数据如下:
数据库数据也已成功 添加
视图库对接系列(本级)注册完成。