阿里云MQTT 客户端收发 MQTT 消息(使用一个设备控制另一个设备)

https://help.aliyun.com/document_detail/44874.html?spm=a2c4g.11186623.6.721.qxegRK
1保证只有一组用户AccessKey,怕冲突其他的可暂时禁用
(踩过的坑:域名必须是这个格式tcp://mqtt-cn-4590pc20t03.mqtt.aliyuncs.com:1883)
(踩过的坑:发送的消息分为两种,一是广播的方式:一方发送,多方接收;二是点对点式的(p2p)只能一个设备控制另一个,不可多个,即三级topic,可使用设备的物理地址作为区分,保证唯一即可String p2pTopic = topic + “/p2p/GID_wangyang8110@@@34:0a:ff:52:01:66”)
最大的一个坑:测试接收消息的时候发现总是不执行messageArrived,其实应该先点击接收消息出现messageArrived,此时点击发送消息,即可看到接收端的日志。取出消息的api是new String(mqttMessage.getPayload())
2 发送消息代码,acessKey secretKey 并不真实,已做处理。

public class MainActivity extends AppCompatActivity {
    /**
     * 设置当前用户私有的MQTT的接入点。例如此处示意使用XXX,实际使用请替换用户自己的接入点。接入点的获取方法是,在控制台申请MQTT实例,每个实例都会分配一个接入点域名。
     */
//        final String broker ="tcp://XXXX.mqtt.aliyuncs.com:1883";
    final String broker = "tcp://mqtt-cn-4590pc20t03.mqtt.aliyuncs.com:1883";
    /**
     * 设置阿里云的AccessKey,用于鉴权
     */
    final String acessKey = "LTAI2jtCdfgOCbJaY1";
    /**
     * 设置阿里云的SecretKey,用于鉴权
     */
    final String secretKey = "FPqp6oQ2JWCEZ6PlxN9eI42wPfnecLZD32";
    /**
     * 发消息使用的一级Topic,需要先在MQ控制台里申请
     */
    final String topic = "wy1";
    /**
     * MQTT的ClientID,一般由两部分组成,GroupID@@@DeviceID
     * 其中GroupID在MQ控制台里申请
     * DeviceID由应用方设置,可能是设备编号等,需要唯一,否则服务端拒绝重复的ClientID连接
     */
//        final String clientId ="GID_XXX@@@ClientID_XXXX";
    String clientId;
    String sign;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        clientId = "GID_wangyang8110@@@" + getWlanId();
        Log.e("1", "clientId: "+ clientId);
    }

    private String getWlanId() {
        WifiManager wm = (WifiManager) getApplicationContext().getSystemService(getApplicationContext().WIFI_SERVICE);
        String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
        return m_szWLANMAC;
    }

    public void send(View mView) {
        MemoryPersistence persistence = new MemoryPersistence();
        try {
            final MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
            final MqttConnectOptions connOpts = new MqttConnectOptions();
            System.out.println("Connecting to broker: " + broker);
            /**
             * 计算签名,将签名作为MQTT的password。
             * 签名的计算方法,参考工具类MacSignature,第一个参数是ClientID的前半部分,即GroupID
             * 第二个参数阿里云的SecretKey
             */
            sign = MacSignature.macSignature(clientId.split("@@@")[0], secretKey);
            connOpts.setUserName(acessKey);
            connOpts.setServerURIs(new String[]{broker});
            connOpts.setPassword(sign.toCharArray());
            connOpts.setCleanSession(true);
            connOpts.setKeepAliveInterval(90);
            connOpts.setMqttVersion(MQTT_VERSION_3_1_1);
            connOpts.setAutomaticReconnect(true);
            sampleClient.setCallback(new MqttCallbackExtended() {
                public void connectComplete(boolean reconnect, String serverURI) {
                    System.out.println("connect success");
                    //连接成功,需要上传客户端所有的订阅关系
                }

                public void connectionLost(Throwable throwable) {
                    System.out.println("mqtt connection lost");
                }

                public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
                    System.out.println("messageArrived:" + topic + "------" + new String(mqttMessage.getPayload()));
                }

                public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
                    System.out.println("deliveryComplete:" + iMqttDeliveryToken.getMessageId());
                }
            });
            sampleClient.connect(connOpts);
            for (int i = 0; i < 1; i++) {
                try {
//                    String scontent = new Date() + "MQTT Test body wangyang" + i;
                    String scontent =  "MQTT Test body wangyang" + i;
                    //此处消息体只需要传入byte数组即可,对于其他类型的消息,请自行完成二进制数据的转换
                    final MqttMessage message = new MqttMessage(scontent.getBytes());
                    message.setQos(0);
                    System.out.println(i + " pushed at " + new Date() + " " + scontent);
                    /**
                     *消息发送到某个主题Topic,所有订阅这个Topic的设备都能收到这个消息。
                     * 遵循MQTT的发布订阅规范,Topic也可以是多级Topic。此处设置了发送到二级Topic
                     */
                    sampleClient.publish(topic + "/notice/", message);
                    /**
                     * 如果发送P2P消息,二级Topic必须是“p2p”,三级Topic是目标的ClientID
                     * 此处设置的三级Topic需要是接收方的ClientID
                     */
//                    String p2pTopic = topic + "/p2p/GID_mqttdelay3@@@DEVICEID_001";
//                    String p2pTopic = topic + "/p2p/GID_wangyang8110@@@34:0a:ff:52:01:66";
//                    sampleClient.publish(p2pTopic, message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception me) {
            me.printStackTrace();
        }
    }
}

3接收端代码

public class RecvActivity extends Activity {
    /**
     * 设置当前用户私有的MQTT的接入点。例如此处示意使用XXX,实际使用请替换用户自己的接入点。接入点的获取方法是,在控制台申请MQTT实例,每个实例都会分配一个接入点域名。
     */
//        final String broker ="tcp://XXXX.mqtt.aliyuncs.com:1883";
    final String broker = "tcp://mqtt-cn-4590pc20t03.mqtt.aliyuncs.com:1883";
    /**
     * 设置阿里云的AccessKey,用于鉴权
     */
    final String acessKey = "LTAI2jtCdfgOCbJaY1";
    /**
     * 设置阿里云的SecretKey,用于鉴权
     */
    final String secretKey = "FPqp6fgoQ2JWCEZ236PlxN9eIwPfnecLZD";
    /**
     * 发消息使用的一级Topic,需要先在MQ控制台里申请
     */
    final String topic = "wy1";
    /**
     * MQTT的ClientID,一般由两部分组成,GroupID@@@DeviceID
     * 其中GroupID在MQ控制台里申请
     * DeviceID由应用方设置,可能是设备编号等,需要唯一,否则服务端拒绝重复的ClientID连接
     */
//        final String clientId ="GID_XXXX@@@ClientID_XXXXXX";
    String clientId ;
    String sign;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recv);
        clientId="GID_wangyang8110@@@"+getWlanId();
        Log.e("1", "clientId: "+ clientId);
//        recv();
    }
    private String getWlanId() {
        WifiManager wm = (WifiManager) getApplicationContext().getSystemService(getApplicationContext().WIFI_SERVICE);
        String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
        return m_szWLANMAC;
    }

    public void recv(View mView) {
        MemoryPersistence persistence = new MemoryPersistence();
        try {
            final MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
            final MqttConnectOptions connOpts = new MqttConnectOptions();
            System.out.println("Connecting to broker: " + broker);
            /**
             * 计算签名,将签名作为MQTT的password
             * 签名的计算方法,参考工具类MacSignature,第一个参数是ClientID的前半部分,即GroupID
             * 第二个参数阿里云的SecretKey
             */
            sign = MacSignature.macSignature(clientId.split("@@@")[0], secretKey);
            /**
             * 设置订阅方订阅的Topic集合,此处遵循MQTT的订阅规则,可以是一级Topic,二级Topic,P2P消息请订阅/p2p
             */
            final String[] topicFilters = new String[]{topic + "/notice/", topic + "/p2p"};
            final int[] qos = {0, 0};
            connOpts.setUserName(acessKey);
            connOpts.setServerURIs(new String[]{broker});
            connOpts.setPassword(sign.toCharArray());
            connOpts.setCleanSession(true);
            connOpts.setKeepAliveInterval(90);
            connOpts.setMqttVersion(MQTT_VERSION_3_1_1);
            connOpts.setAutomaticReconnect(true);
            sampleClient.setCallback(new MqttCallbackExtended() {
                public void connectComplete(boolean reconnect, String serverURI) {
                    System.out.println("rev connect success");
                    //连接成功,需要上传客户端所有的订阅关系
                    try {
                        sampleClient.subscribe(topicFilters, qos);
                    } catch (MqttException mE) {
                        mE.printStackTrace();
                    }
                }

                public void connectionLost(Throwable throwable) {
                    System.out.println("mqtt connection lost");
                }

                public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
                    System.out.println("接收到消息:"+new String(mqttMessage.getPayload()));
                    System.out.println("messageArrived  topic:" + topic +"------接收到消息:" + new String(mqttMessage.getPayload()));
                }

                public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
                    System.out.println("deliveryComplete:" + iMqttDeliveryToken.getMessageId());
                }
            });
            //客户端每次上线都必须上传自己所有涉及的订阅关系,否则可能会导致消息接收延迟
            sampleClient.connect(connOpts);
            //每个客户端最多允许存在30个订阅关系,超出限制可能会丢弃导致收不到部分消息
            sampleClient.subscribe(topicFilters, qos);
            Thread.sleep(Integer.MAX_VALUE);
        } catch (Exception me) {
            me.printStackTrace();
        }
    }
}

你可能感兴趣的:(Android)