一、项目描述
使用sprinboot实现后端的数据处理。前端页面使用x-admin作为管理页面。
二、项目过程
1、实现java端向阿里云发送消息
主要参考阿里云的文档🔗
利用topic进行消息的分发。
①接收阿里云发送的消息
private final static Logger logger = LoggerFactory.getLogger(AliController.class);
//初始化线程池
private final static ExecutorService executorService = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(),
Runtime.getRuntime().availableProcessors() * 2, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(50000));
//初始化连接
@Override
public void run(String... args) throws Exception {
//参数说明,请参见AMQP客户端接入说明文档。
String accessKey = "";
String accessSecret = "";
String consumerGroupId = "";
String iotInstanceId = "";
long timeStamp = System.currentTimeMillis();
String signMethod = "hmacsha1";
String clientId = "";
String userName = clientId + "|authMode=aksign"
+ ",signMethod=" + signMethod
+ ",timestamp=" + timeStamp
+ ",authId=" + accessKey
+ ",iotInstanceId=" + iotInstanceId
+ ",consumerGroupId=" + consumerGroupId
+ "|";
String signContent = "authId=" + accessKey + "×tamp=" + timeStamp;
String password = doSign(signContent,accessSecret, signMethod);
String connectionUrl = "failover:(amqps://1853300655099694.iot-amqp.cn-shanghai.aliyuncs.com:5671?amqp.idleTimeout=80000)?failover.reconnectDelay=30";
Hashtable<String, String> hashtable = new Hashtable<>();
hashtable.put("connectionfactory.SBCF",connectionUrl);
hashtable.put("queue.QUEUE", "default");
hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
Context context = new InitialContext(hashtable);
ConnectionFactory cf = (ConnectionFactory)context.lookup("SBCF");
Destination queue = (Destination)context.lookup("QUEUE");
// Create Connection
connection = cf.createConnection(userName, password);
((JmsConnection) connection).addConnectionListener(myJmsConnectionListener);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
//Create Receiver Link
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(messageListener);
}
public static final MessageListener messageListener = new MessageListener() {
@Override
public void onMessage(Message message) {
try {
executorService.submit(() -> processMessage(message));
} catch (Exception e) {
logger.error("submit task occurs exception ", e);
}
}
};
public static void processMessage(Message message) {
try {
byte[] body = message.getBody(byte[].class);
String content = new String(body);
String topic = message.getStringProperty("topic");
deviceName = AliController.getDeviceName();
//计算此条信息中包含的功率
try{
JSONObject paramsObject = JSONObject.parseObject(content).getJSONObject("params");
nowDeviceName = Utilsss.getDeviceNameByTopic(topic);
voltage = paramsObject.get("voltage").toString();
current = paramsObject.get("current").toString();
power = paramsObject.get("power").toString();
energy = paramsObject.get("energy").toString();
temp = paramsObject.get("temp").toString();
humi = paramsObject.get("humi").toString();
device0 = new Device(power,energy,new Date(),nowDeviceName);
}catch (Exception e){
e.printStackTrace();
}
} catch (Exception e) {
logger.error("processMessage occurs error ", e);
}
}
②通过topic向设备发送消息
@GetMapping("/sendWiFiInfo")
public static String sendWiFiInfoToAli(@RequestParam("wifiName")String wifiName,@RequestParam("wifiPass") String wifiPassword,@RequestParam("deviceName") String deviceName) throws UnsupportedEncodingException {
Map<String,String> wifiMap = new HashMap<>();
wifiMap.put("wifiName",wifiName);
wifiMap.put("wifiPassword",wifiPassword);
String wifijsonString = JSON.toJSONString(wifiMap);
String wifiInfobase64 = java.util.Base64.getEncoder().encodeToString(wifijsonString.getBytes(StandardCharsets.UTF_8));
DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", "", "");
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain("iot.cn-shanghai.aliyuncs.com");
request.setSysVersion("2018-01-20");
request.setSysAction("RRpc") ;
request.putQueryParameter("RegionId", "cn-shanghai");
request.putQueryParameter("DeviceName", deviceName);
request.putQueryParameter("Timeout", "3000");
request.putQueryParameter("RequestBase64Byte", wifiInfobase64);
request.putQueryParameter("ProductKey", "");
try {
CommonResponse response = client.getCommonResponse(request);
return "ok";
} catch (Exception e) {
e.printStackTrace();
return "false";
}
}
当执行这个方法,传入wifiname和wifipass这两个参数后,会通过rrpc协议传输数据,当设备接收到数据后,会调用