Работа с 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
.