java连接阿里云物联网(服务器端)
创建服务端订阅(如果没有创建的话,服务器接收不到信息)
这个是默认的消费组,也可以自新定义一个然后修改后面的CONSUMER_GROUP_ID字段为新定义的
导包(这里是所有的)
<dependency>
<groupId>com.aliyun.alink.linksdk</groupId>
<artifactId>iot-linkkit-java</artifactId>
<version>1.2.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.aliyun.alink.linksdk</groupId>
<artifactId>public-cmp-java</artifactId>
<version>1.3.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>iot-client-message</artifactId>
<version>1.1.5</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-iot</artifactId>
<version>7.7.0</version>
</dependency>
<!-- amqp 1.0 qpid client -->
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-jms-client</artifactId>
<version>0.47.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
配置信息类
参考配置信息
public interface DeviceInfoData {
//这些信息要去阿里云平台获取
String REGION_ID = "cn-shanghai";
String ACCESS_KEY = "";
String ACCESS_SECRET = "";
//三元组信息
String DEVICE_NAME = "";
String PRODUCT_KEY = "";
String DEVICE_SECRET = "";
//iotInstanceId:购买的实例请填写实例ID,公共实例请填空字符串""。
String IOT_ID="";
//您的阿里云账号ID。用主账号登录阿里云控制台,单击账号头像,跳转至账号管理控制台,即可获取账号UID。
String UID = "";
//控制台服务端订阅中消费组状态页客户端ID一栏将显示clientId参数。
//建议使用机器UUID、MAC地址、IP等唯一标识等作为clientId。便于您区分识别不同的客户端。
String CLIENT_ID = "";
//消费组ID
String CONSUMER_GROUP_ID = "DEFAULT_GROUP";
}
ACCESS_KEY,ACCESS_SECRET的获取
物联网设备信息接受并进行相应的业务
@Slf4j
@Component
public class ServerIOT {
/**
* 业务处理异步线程池,线程池参数可以根据您的业务特点调整;或者您也可以用其他异步方式处理接收到的消息
*/
private final static ExecutorService executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().availableProcessors() * 2, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(50000));
static final String consumerGroupId = DeviceInfoData.CONSUMER_GROUP_ID;
//签名方法:支持hmacmd5,hmacsha1和hmacsha256
static final String signMethod = "hmacsha1";
//控制台服务端订阅中消费组状态页客户端ID一栏将显示clientId参数。
//建议使用机器UUID、MAC地址、IP等唯一标识等作为clientId。便于您区分识别不同的客户端。
static final String clientId = DeviceInfoData.CLIENT_ID;
static final String uid = DeviceInfoData.UID;
public void ServerIOTControl() throws Exception {
long timeStamp = System.currentTimeMillis();
//UserName组装方法,请参见文档:AMQP客户端接入说明。
String userName = clientId + "|authMode=aksign"
+ ",signMethod=" + signMethod
+ ",timestamp=" + timeStamp
+ ",authId=" + DeviceInfoData.ACCESS_KEY
+ ",consumerGroupId=" + consumerGroupId
+ "|";
//password组装方法,请参见文档:AMQP客户端接入说明。
String signContent = "authId=" + DeviceInfoData.ACCESS_KEY + "×tamp=" + timeStamp;
String password = doSign(signContent);
//按照qpid-jms的规范,组装连接URL。
String connectionUrl = "failover:(amqps://" + uid + ".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 connection = cf.createConnection(userName, password);
((JmsConnection) connection).addConnectionListener(myJmsConnectionListener);
// Create Session
// Session.CLIENT_ACKNOWLEDGE: 收到消息后,需要手动调用message.acknowledge()
// Session.AUTO_ACKNOWLEDGE: SDK自动ACK(推荐)
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
// Create Receiver Link
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(messageListener);
}
/**
* IOT消息监听
*/
private final MessageListener messageListener = message -> {
try {
//1.收到消息之后一定要ACK
// 推荐做法:创建Session选择Session.AUTO_ACKNOWLEDGE,这里会自动ACK。
// 其他做法:创建Session选择Session.CLIENT_ACKNOWLEDGE,这里一定要调message.acknowledge()来ACK。
// message.acknowledge();
//2.建议异步处理收到的消息,确保onMessage函数里没有耗时逻辑。
// 如果业务处理耗时过程过长阻塞住线程,可能会影响SDK收到消息后的正常回调。
executorService.submit(() -> processMessage(message));
//如果创建Session选择的是Session.CLIENT_ACKNOWLEDGE,这里需要手动ACK。
//message.acknowledge();
//如果要对收到的消息做耗时的处理,请异步处理,确保这里不要有耗时逻辑。
} catch (Exception e) {
e.printStackTrace();
}
};
//信息接受,并处理相应的业务
private void processMessage(Message message) {
try {
byte[] body = message.getBody(byte[].class);
//content就是阿里云平台发来的json信息,根据这个就可以进行相应的业务处理
String content = new String(body);
log.info("content=========>" + content);
} catch (JMSException e) {
log.error("processMessage occurs error ", e);
}
}
/**
* IOT连接监听
*/
private final JmsConnectionListener myJmsConnectionListener = new JmsConnectionListener() {
/**
* 连接成功建立。
*/
@Override
public void onConnectionEstablished(URI remoteURI) {
log.info("onConnectionEstablished, remoteUri:{}", remoteURI);
}
/**
* 尝试过最大重试次数之后,最终连接失败。
*/
@Override
public void onConnectionFailure(Throwable error) {
log.error("onConnectionFailure, {}", error.getMessage());
}
/**
* 连接中断。
*/
@Override
public void onConnectionInterrupted(URI remoteURI) {
log.info("onConnectionInterrupted, remoteUri:{}", remoteURI);
}
/**
* 连接中断后又自动重连上。
*/
@Override
public void onConnectionRestored(URI remoteURI) {
log.info("onConnectionRestored, remoteUri:{}", remoteURI);
}
@Override
public void onInboundMessage(JmsInboundMessageDispatch envelope) {
}
@Override
public void onSessionClosed(Session session, Throwable cause) {
}
@Override
public void onConsumerClosed(MessageConsumer consumer, Throwable cause) {
}
@Override
public void onProducerClosed(MessageProducer producer, Throwable cause) {
}
};
/**
* password签名计算方法,请参见文档:AMQP客户端接入说明。
*/
private String doSign(String toSignString) throws Exception {
SecretKeySpec signingKey = new SecretKeySpec(DeviceInfoData.ACCESS_SECRET.getBytes(), ServerIOT.signMethod);
Mac mac = Mac.getInstance(ServerIOT.signMethod);
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(toSignString.getBytes());
return Base64.encodeBase64String(rawHmac);
}
}
参考阿里云文档