1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/596392912-mica-mqtt

 / Детали:

Клиент Eclipse Paho MQTT WebSocket подключается к серверу MICA-MQTT с ошибкой.

Предстоит сделать
Владелец
Создано  
12.03.2025

Версия mica-mqtt

2.4.x

Используемые компоненты

mica-mqtt-server

Конкретные версии и сценарии использования

Использование eclipse paho mqtt websocket client для подключения к mica-mqtt server привело к ошибкам.

Описание проблемы (внимание: если проблема описана неправильно, запрос будет закрыт)

Анномальная информация:
Введите описание изображения

Причина проблемы:
Допущена ошибка в кодировке заголовка HTTP-сообщения, что не соответствует правилам кодирования HTTP. Клиент eclipse paho mqtt websocket строго проверяет эти правила.

Анализ сообщения:

Ответ от mica-net:

HTTP/1.1 101 Switching Protocols\r\n
server: mica-net\r\n
date: Wed, 19 Feb 2025 08:44:44 GMT\r\n
sec-websocket-protocol: mqtt\r\n
content-length: 0\r\n
upgrade: WebSocket\r\n
connection: Upgrade\r\n
sec-websocket-accept: Ax1fAV7Wxcb+jRIxCGT/nuEzadE=\r\n
\r\n

Проверка paho.mqtt
https://github.com/eclipse-paho/paho.mqtt.java/blob/9c742c1d83e71132452e08d325e5a90d1631c302/org.eclipse.paho.mqttv5.client/src/main/java/org/eclipse/paho/mqttv5/client/websocket/WebSocketHandshake.java#L152

Нормальный ответ HTTP-сообщения должен содержать пробел после двоеточия в заголовках. Пример (ответ EMQX):

HTTP/1.1 101 Switching Protocols\r\n
connection: Upgrade\r\n
date: Wed, 19 Feb 2025 00:57:41 GMT\r\n
sec-websocket-accept: yLgy5oAwNdroPHjshpG4TL3CMD0=\r\n
sec-websocket-protocol: mqtt\r\n
server: Cowboy\r\n
upgrade: websocket\r\n
\r\n

Альтернативное решение — использование hivemq-mqtt-client websocket:
Добавление зависимостей:

<dependency>
    <groupId>com.hivemq</groupId>
    <artifactId>hivemq-mqtt-client</artifactId>
    <version>1.3.5</version>
</dependency>
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-codec-http</artifactId>
    <version>4.1.101.Final</version>
</dependency>
```**Пример использования:**
```java
import com.hivemq.client.mqtt.*;
import com.hivemq.client.mqtt.datatypes.MqttQos;
import com.hivemq.client.mqtt.mqtt5.*;
import com.hivemq.client.mqtt.mqtt5.message.connect.Mqtt5ConnectBuilder;
import com.hivemq.client.mqtt.mqtt5.message.connect.connack.Mqtt5ConnAck;
import java.util.concurrent.CompletableFuture;

public class MqttWebSocketExample {
``````java
    public static void main(String[] args) {
        // Создание MQTT клиента
        Mqtt5Client client = MqttClient.builder()
            .webSocketWithDefaultConfig()
            .useMqttVersion5()
            .serverHost("127.0.0.1")
            .serverPort(8083)
            .identifier("java-client-" + System.currentTimeMillis())
            .buildAsync();
``````java
        // Настройка соединения
        Mqtt5ConnectBuilder.Send<CompletableFuture<Mqtt5ConnAck>> connectOptions = client.toAsync()
                .connectWith()
                .cleanStart(true)
                .keepAlive(30);

        // Асинхронное подключение
        connectOptions.send().whenComplete((connAck, throwable) -> {
            if (throwable != null) {
                System.err.println("Подключение не удалось: " + throwable.getMessage());
            } else {
                System.out.println("Успешное подключение к серверу!");

                // Подписка на тему
                client.toAsync().subscribeWith()
                        .topicFilter("test/topic")
                        .qos(MqttQos.AT_LEAST_ONCE)
                        .callback(publish -> {
                            System.out.println("Получено сообщение: " + new String(publish.getPayloadAsBytes()));
                        })
                        .send();

                // Отправка сообщения
                client.toAsync().publishWith()
                        .topic("test/topic")
                        .payload("Привет от Java!".getBytes())
                        .qos(MqttQos.AT_LEAST_ONCE)
                        .send();
            }
        });
    }
}
```        // Сохранение программы в активном состоянии
        try {
            Thread.sleep(60000); // Сохранение соединения 60 секунд
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        client.toAsync().disconnect();
    }
}**HTTP протокол запроса заголовков:**
- Протокол позволяет иметь произвольное количество символов LWS (линейного белого пространства) перед значением поля.
- Рекомендовано использовать один пробел (SP) для поддержания чистоты и согласованности.
- В реальных приложениях нет обязательного требования наличия пробела, но следование рекомендациям является лучшим подходом.

**Заключение:**
Чувствую, что ограничения `paho.mqtt` кажутся незаслуженными, стоит рассмотреть возможность прямой поддержки WebSocket в будущей версии клиента MICA-MQTT.

Комментарий (0)

GitLife Service Account Задача создана

Вход Перед тем как оставить комментарий

Статус
Ответственный
Контрольная точка
Pull Requests
Связанные запросы на слияние могут быть закрыты после их объединения
Ветки
Дата начала   -   Крайний срок
-
Закрепить/Открепить
Приоритет
Участники(1)
1
https://api.gitlife.ru/oschina-mirror/596392912-mica-mqtt.git
git@api.gitlife.ru:oschina-mirror/596392912-mica-mqtt.git
oschina-mirror
596392912-mica-mqtt
596392912-mica-mqtt