java连接阿里云物联网(服务器端)

创建服务端订阅(如果没有创建的话,服务器接收不到信息)

java 开源物联网数据采集平台 java对接物联网_java 开源物联网数据采集平台


java 开源物联网数据采集平台 java对接物联网_java_02


java 开源物联网数据采集平台 java对接物联网_ide_03

这个是默认的消费组,也可以自新定义一个然后修改后面的CONSUMER_GROUP_ID字段为新定义的

java 开源物联网数据采集平台 java对接物联网_阿里云_04

导包(这里是所有的)

<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的获取

java 开源物联网数据采集平台 java对接物联网_阿里云_05

物联网设备信息接受并进行相应的业务

@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);
    }



}

参考阿里云文档