package com.ruoyi.iot.receive;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.iot.domain.ObjBody;
import com.ruoyi.iot.domain.ReceiveMsg;
import com.ruoyi.iot.service.IotReceiveService;
import com.ruoyi.iot.util.IotUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 接收硬件参数
*
* @author ruoyi
*/
@RestController
@RequestMapping("/iot")
public class ReceiveController {
private static final Logger log = LoggerFactory.getLogger(ReceiveController.class);
@Value(value = "${iot.token}")
private String token;
@Autowired
private IotReceiveService iotReceiveService;
@Autowired
private ScheduledExecutorService scheduledExecutorService;
/**
* 功能描述:第三方平台数据接收。
*
注:
* - 1.OneNet平台为了保证数据不丢失,有重发机制,如果重复数据对业务有影响,数据接收端需要对重复数据进行排除重复处理。
* - 2.OneNet每一次post数据请求后,等待客户端的响应都设有时限,在规定时限内没有收到响应会认为发送失败。
* 接收程序接收到数据时,尽量先缓存起来,再做业务逻辑处理。
*
* @param body 数据消息
* @return 任意字符串。OneNet平台接收到http 200的响应,才会认为数据推送成功,否则会重发。
*/
@PostMapping(value = "/receive")
@Anonymous
public ResponseEntity receive(HttpServletRequest request){
// 异步处理,直接返回成功
scheduledExecutorService.schedule(() -> {
String body = HttpUtils.getBody(request);
ObjBody obj = IotUtil.resolveBody(body, false);
if (obj != null){
Object msg = obj.getMsg();
// 接收到msg
if (msg instanceof String) {
iotReceiveService.handleReceive(JSON.parseObject((String) msg, ReceiveMsg.class));
} else {
iotReceiveService.handleReceive(JSON.parseObject(JSON.toJSONString(msg), ReceiveMsg.class));
}
}else {
log.error("receive方法参数为空: body empty error");
}
}, 0, TimeUnit.SECONDS);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* 功能说明: URL&Token验证接口。如果验证成功返回msg的值,否则返回其他值。
* @param msg 验证消息
* @param nonce 随机串
* @param signature 签名
* @return msg值
*/
@RequestMapping(value = "/receive", method = RequestMethod.GET)
public String check(@RequestParam(value = "msg") String msg,
@RequestParam(value = "nonce") String nonce,
@RequestParam(value = "signature") String signature) throws UnsupportedEncodingException {
log.info("check方法接收到参数:: msg:{} nonce{} signature:{}",msg,nonce,signature);
if (IotUtil.checkToken(msg,nonce,signature,token)){
return msg;
}else {
return "error";
}
}
}