Работа с Yandex IoT Core с устройства Android на языке Java
В этом руководстве вы узнаете как подключиться к Yandex IoT Core с устройства Android с помощью библиотеки Paho
Примечание
Исходный код руководства доступен в репозитории на GitHub
После подключения вы сможете обмениваться сообщениями между устройством и реестром:
Чтобы подключиться к Yandex IoT Core и начать обмен сообщениями:
- Создайте необходимые ресурсы Yandex IoT Core:
- Подключитесь к Yandex IoT Core.
- Аутентифицируйтесь в Yandex IoT Core:
- Установите соединение.
- Подпишитесь на топик и принимайте сообщения с данными.
- Отправьте сообщение с данными.
- Завершите соединение.
Перед началом работы
- Если у вас еще нет интерфейса командной строки Yandex Cloud, установите и инициализируйте его.
- Скачайте и установите Android Studio
— среду разработки для операционной системы Android.
Создайте необходимые ресурсы Yandex IoT Core
Создайте реестр и добавьте ему сертификат
Если у вас уже есть сертификат, перейдите сразу ко второму шагу.
-
Создайте сертификат для реестра (пропустите этот шаг, если у вас уже есть сертификат реестра):
openssl req -x509 \ -newkey rsa:4096 \ -keyout registry-key.pem \ -out registry-cert.pem \ -nodes \ -days 365 \ -subj '/CN=localhost' -
Создайте реестр:
yc iot registry create --name my-registry -
Добавьте сертификат реестру:
yc iot registry certificate add \ --registry-name my-registry \ # Имя реестра. --certificate-file registry-cert.pem # Путь к публичной части сертификата.
Создайте устройство и добавьте ему сертификат
Если у вас уже есть сертификат, перейдите сразу ко второму шагу.
-
(опционально) Создайте сертификат для устройства:
openssl req -x509 \ -newkey rsa:4096 \ -keyout device-key.pem \ -out device-cert.pem \ -nodes \ -days 365 \ -subj '/CN=localhost' -
Создайте устройство:
yc iot device create --name my-device -
Добавьте сертификат устройству:
yc iot device certificate add \ --device-name my-device \ # Имя устройства. --certificate-file device-cert.pem # Путь к публичной части сертификата.
Подключитесь к Yandex IoT Core
Перед подключением настройте параметры соединения с помощью следующего кода:
String clientId = "YandexIoTCoreAndroidTextClient";
int connectionTimeout = 60;
int keepAliveInterval = 60;
MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(getApplicationContext(),"ssl://mqtt.cloud.yandex.net:8883", clientId);
// Настройка параметров соединения.
MqttConnectOptions options = new MqttConnectOptions();
options.setKeepAliveInterval(keepAliveInterval);
Где:
MqttAndroidClient— класс, в котором указываются параметры подключения к Yandex IoT Core. Адрес, порт и идентификатор клиента.MqttConnectOptions— класс для установки параметров соединения. Вы можете оставить настройки по умолчанию, но рекомендуется задать параметрKeepAliveInterval. От его значения зависит частота отправки командPINGREQ. Чем меньше данный параметр, тем быстрее клиент понимает, что соединение было разорвано нештатным путем. Но для этого чаще отправляются тарифицируемые командыPINGREQ.
Аутентифицируйтесь в Yandex IoT Core
Есть два способа аутентификации:
Аутентификация с помощью X.509-сертификатов
Для такого вида аутентификации удобнее всего использовать сертификаты PKCS#12
openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12
Для загрузки сертификатов в проекте используйте метод:
private SSLSocketFactory getSocketFactory(final InputStream caCrtFile, final InputStream devCert, final String password)
Загрузка сертификатов происходит в несколько этапов:
-
Загрузите сертификат, используемый для аутентификации сервера:
// Загрузка сертификата удостоверяющего центра. CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate caCert = (X509Certificate) cf.generateCertificate(caCrtFile); // Использование сертификата удостоверяющего центра для аутентификации сервера. KeyStore serverCaKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); serverCaKeyStore.load(null, null); serverCaKeyStore.setCertificateEntry("ca", caCert); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(serverCaKeyStore); -
Загрузите сертификат клиента, используемый для аутентификации на сервере:
KeyStore clientKeystore = KeyStore.getInstance("PKCS12"); clientKeystore.load(devCert, password.toCharArray());
В результате метод возвращает AdditionalKeyStoresSSLSocketFactory:
return new AdditionalKeyStoresSSLSocketFactory(clientKeystore, serverCaKeyStore);
Класс AdditionalKeyStoresSSLSocketFactory является наследником SSLSocketFactory и используется для работы с самоподписанными сертификатами. На последнем этапе полученный выше sslSocketFactory нужно передать в параметры соединения:
options.setSocketFactory(sslSocketFactory);
Аутентификация по логину и паролю
Так как Yandex IoT Core требует TLS-протокол при аутентификации с помощью логина и пароля, инициализируйте класс AdditionalKeyStoresSSLSocketFactory с помощью метода:
private SSLSocketFactory getSocketFactory(final InputStream caCrtFile, final InputStream devCert, final String password)
В качестве devCert передайте значение null. В этом случае будет загружен только сертификат удостоверяющего центра сервера:
// Загрузка сертификата удостоверяющего центра.
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate) cf.generateCertificate(caCrtFile);
// Использование сертификата удостоверяющего центра для аутентификации сервера.
KeyStore serverCaKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
serverCaKeyStore.load(null, null);
serverCaKeyStore.setCertificateEntry("ca", caCert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(serverCaKeyStore);
return new AdditionalKeyStoresSSLSocketFactory(null, serverCaKeyStore);
В настройках соединения укажите логин (идентификатор реестра или устройства) и пароль:
options.setUserName(mqttUserName);
options.setPassword(mqttPassword.toCharArray());
и SSLSocketFactory, полученный из кода выше:
options.setSocketFactory(sslSocketFactory);
Установите соединение
Установите соединение с Yandex IoT Core с помощью следующего кода:
mqttAndroidClient.connect(options,null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
}
});
Подпишитесь на топик и принимайте сообщения с данными
Для обработки полученных данных используйте функцию обратного вызова:
mqttAndroidClient.setCallback(new MqttCallback() {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception { }
});
Подпишитесь на топик с помощью следующего кода. В методе subscribe нужно указать топик, на который вы хотите подписаться, и уровень качества обслуживания.
IMqttToken subToken = mqttAndroidClient.subscribe(topic, qos);
subToken.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
// Публикация сообщения.
}
@Override
public void onFailure(IMqttToken asyncActionToken,
Throwable exception) {
// Подписка на сообщение не может быть выполнена. Возможно, пользователь не был
// авторизован для подписки на указанный топик.
System.out.println("Failed to subscribe");
}
});
Отправьте сообщение с данными
Отправьте сообщения с помощью следующего кода. В методе publish нужно указать топик, в который вы хотите отправить сообщение, и текст сообщения. Опционально вы можете указать желаемый уровень качества обслуживания для экземпляра класса MqttMessage.
IMqttDeliveryToken publish = mqttAndroidClient.publish("<топик>", new MqttMessage("Your message text.".getBytes()));
Обрабатывайте события об обрыве связи и отслеживайте доставку сообщений с помощью функций обратного вызова:
mqttAndroidClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
}
});
Завершите соединение
Завершите соединение с Yandex IoT Core с помощью методов:
mqttAndroidClient.disconnect();
mqttAndroidClient.close();
Где:
- Метод
disconnectзакрывает соединение с сервером. - Метод
closeосвобождает ресурсы классаMqttAndroidClient.