Работа с Yandex IoT Core на языке Java
В этом сценарии вы узнаете, как подключиться к Yandex IoT Core с помощью библиотеки Paho
Примечание
Исходный код, который используется в этом сценарии, доступен на GitHub
После подключения вы сможете:
Чтобы подключиться к Yandex IoT Core и начать обмен сообщениями:
- Создайте необходимые ресурсы Yandex IoT Core:
- Подключитесь к Yandex IoT Core.
- Аутентифицируйтесь в Yandex IoT Core:
- Установите соединение.
- Подпишитесь на топик и получайте сообщения.
- Отправьте сообщение.
- Завершите соединение.
Перед началом работы
- Если у вас еще нет интерфейса командной строки Yandex Cloud, установите и инициализируйте его.
- Скачайте и установите Java Development Kit
.
Создайте необходимые ресурсы 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 --registry-name my-registry --name my-device
-
Добавьте сертификат устройству:
yc iot device certificate add \ --device-name my-device \ # Имя устройства. --certificate-file device-cert.pem # Путь к публичной части сертификата.
Подключитесь к Yandex IoT Core
Перед подключением настройте параметры соединения connOpts
с помощью следующего кода:
String clientId = "YandexIoTCoreTestJavaClient";
int keepAliveInterval = 60;
MqttClient client = new MqttClient("ssl://mqtt.cloud.yandex.net:8883", clientId);
// Установка обработчика асинхронных событий
client.setCallback(listener);
// Настройка параметров соединения.
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setKeepAliveInterval(keepAliveInterval);
Где:
MqttClient
— класс, в котором указываются параметры подключения к Yandex IoT Core:- Адрес и порт.
- Идентификатор клиента.
MqttConnectOptions
— класс для установки параметров соединения. Вы можете оставить настройки по умолчанию, но рекомендуется задать параметрkeepAliveInterval
. От его значения зависит частота отправки командPINGREQ
. Чем меньше значениеkeepAliveInterval
, тем быстрее клиент понимает, что соединение было разорвано нештатным путем. Но для этого чаще отправляются тарифицируемые командыPINGREQ
.listener
— класс, реализующий интерфейсMqttCallback
. Он используется для обработки событий о потере связи с сервером (connectionLost
), доставке сообщения (deliveryComplete
) и получении нового сообщения (messageArrived
).
Аутентифицируйтесь в Yandex IoT Core
Есть два способа аутентификации:
Аутентификация с помощью сертификатов
При аутентификации с помощью X.509-сертификатов используются сертификаты в формате PKCS#12
openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12
Структура файлов
В примере, доступном на GitHub
/my_registry Директория реестра |текущая директория|. Пример нужно запускать из этой директории.
`- /device Директория устройства |device|.
| `- cert.pem Сертификат устройства в PEM-формате.
| `- key.pem Ключ устройства в PEM-формате.
| `- keystore.p12 Сертификат и ключ устройства в PKCS#12-формате.
`- cert.pem Сертификат реестра в PEM-формате.
`- key.pem Ключ реестра в PEM-формате.
`- keystore.p12 Сертификат и ключ реестра в PKCS#12-формате.
Загрузка сертификатов
Сертификат удостоверяющего центра задан в виде статической переменной TRUSTED_ROOT
.
Для загрузки сертификатов в примере используется метод:
private SSLSocketFactory getSocketFactoryWithCerts(String certsDir)
Загрузка сертификатов происходит в несколько этапов:
-
Загрузите сертификат, используемый для аутентификации сервера:
// Загрузка сертификата удостоверяющего центра из статической переменной `TRUSTED_ROOT`. InputStream is = new ByteArrayInputStream(TRUSTED_ROOT.getBytes(StandardCharsets.UTF_8)); CertificateFactory cFactory = CertificateFactory.getInstance("X.509"); X509Certificate caCert = (X509Certificate) cFactory.generateCertificate(is); // Использование сертификата удостоверяющего центра для аутентификации сервера. KeyStore tks = KeyStore.getInstance(KeyStore.getDefaultType()); tks.load(null); tks.setCertificateEntry("caCert", caCert); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(tks);
-
Загрузите сертификат клиента, используемый для аутентификации на сервере, из файла
keystore.p12
:final char[] emptyPassword = "".toCharArray(); KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream(Paths.get(certsDir, "keystore.p12").toString()), emptyPassword); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, emptyPassword);
-
Получите экземпляр класса
SSLSocketFactory
:SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SSLSocketFactory sslSocketFactory = ctx.getSocketFactory();
После чего полученный выше экземпляр sslSocketFactory
нужно передать в параметры соединения:
connOpts.setSocketFactory(sslSocketFactory);
Аутентификация по логину и паролю
Так как при аутентификации по логину и паролю Yandex IoT Core требует TLS-протокол, то необходимо загрузить сертификат, используемый для аутентификации сервера:
//Загружаем сертификат удостоверяющего центра из статической переменной `TRUSTED_ROOT`.
private SSLSocketFactory getSocketFactory()
throws Exception {
InputStream is = new ByteArrayInputStream(TRUSTED_ROOT.getBytes(StandardCharsets.UTF_8));
CertificateFactory cFactory = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate) cFactory.generateCertificate(
is);
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore tks = KeyStore.getInstance(KeyStore.getDefaultType());
tks.load(null); // Вам не нужно загружать из файла экземпляр класса `KeyStore`.
tks.setCertificateEntry("caCert", caCert);
tmf.init(tks);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
return ctx.getSocketFactory();
}
В настройках соединения укажите логин (идентификатор реестра или устройства) и пароль:
connOpts.setUserName(login.trim());
connOpts.setPassword(password.trim().toCharArray());
и sslSocketFactory
, получаемый из кода выше:
SSLSocketFactory sslSocketFactory = getSocketFactory();
connOpts.setSocketFactory(sslSocketFactory);
Установите соединение
Установите соединение с Yandex IoT Core с помощью метода:
client.connect(connOpts);
Метод connect
является блокирующим. Выход из него происходит после завершения процесса установки соединения.
Для обработки события о потере связи с сервером вы можете использовать метод connectionLost
интерфейса MqttCallback
:
@Override
public void connectionLost(Throwable cause) {
}
При этом установить обработчик событий (с помощью метода setCallback
) необходимо до вызова метода connect
:
client.setCallback(listener);
...
client.connect(connOpts);
...
Где listener
— класс, реализующий интерфейс MqttCallback
.
Подпишитесь на топик и получайте сообщения
Подпишитесь на топик с помощью следующего кода. В методе subscribe
нужно указать топик topic
, на который вы хотите подписаться, и уровень качества обслуживания qos
.
client.subscribe(topic, qos);
Для обработки события о получении нового сообщения вы можете использовать метод messageArrived
интерфейса MqttCallback
:
@Override
public void messageArrived(String topic, MqttMessage message){
}
При этом установить обработчик событий (с помощью метода setCallback
) необходимо до вызова метода connect
:
client.setCallback(listener);
...
client.connect(connOpts);
...
Где listener
— класс, реализующий интерфейс MqttCallback
.
Также для обработки события о получении нового сообщения вы можете использовать метод messageArrived
интерфейса IMqttMessageListener
:
client.subscribe(topic, qos, messageListener);
Где messageListener
— класс, реализующий интерфейс IMqttMessageListener
.
Отправьте сообщение
Отправьте сообщение с помощью следующего кода. В методе publish
нужно указать топик topic
, в который вы хотите отправить сообщение, и текст сообщения с помощью класса MqttMessage
. При необходимости можно указать желаемый уровень качества обслуживания qos
для экземпляра класса MqttMessage
.
MqttMessage msg = new MqttMessage(message);
msg.setQos(qos);
client.publish(topic, msg);
Для обработки события о доставке сообщения вы можете использовать метод deliveryComplete
интерфейса MqttCallback
:
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
}
При этом установить обработчик событий (с помощью метода setCallback
) необходимо до вызова метода connect
:
client.setCallback(listener);
...
client.connect(connOpts);
...
Где listener
— класс, реализующий интерфейс MqttCallback
.
Завершите соединение
Завершите соединение с Yandex IoT Core с помощью методов:
client.disconnect();
client.close();
Где:
- Метод
disconnect
закрывает соединение с сервером. - Метод
close
освобождает ресурсы классаMqttClient
.