Java.net.http.WebSocket не отправляет сегменты сообщения размером более 16 КБ ⇐ JAVA
-
Гость
Java.net.http.WebSocket не отправляет сегменты сообщения размером более 16 КБ
Мое клиентское приложение Java отправляет данные на сервер через WebSocket. В некоторых редких случаях данные превышают 16 тыс. Код разбивает данные на сегменты и отправляет их один за другим с помощью метода
ws.sendBinary(segmentMessageData, false).join();.
При отправке последнего сегмента второй аргумент имеет значение true. Отправлен первый сегмент 16 тыс. Когда отправляется второй (последний) сегмент, я получаю сообщение об ошибке:
СЕРЬЕЗНЫЙ: WebSocketClientPeer#onClose statusCode [1009], причина [Нет поддержки асинхронных сообщений и слишком маленький буфер. Размер буфера: [16 384], Размер сообщения: [1 656]] Как видите, буфер значительно больше данных. WebSocket открывается с помощью компоновщика
import java.net.http.WebSocket; // ... WebSocket.Builder wsBuilder = HttpClient.newHttpClient().newWebSocketBuilder(); ws = wsBuilder.buildAsync(URI.create("wss://myserver.dummy.com/wsweb"), this).join(); Клиентский код использует веб-сокет Java 11. Серверная часть использует Tomcat WebSocket. Сервер прекрасно отправляет данные размером более 16 КБ, а Java-клиент получает их (и объединяет в один пакет).
Это устаревшее приложение, в котором сервер находится в облаке и используется WebSocket. Существует реализация, которая использует собственный клиент Windows C++, и она работает нормально. Нам нужен независимый от платформы клиент.
Как отправить более 16 тыс. данных с помощью Java 11 WebSocket?
Обратите внимание: отправка работает нормально, если размер данных меньше 16 КБ и нет фрагментации.
Обнаружил странную вещь:
Если сумма двух сегментов i меньше или равна 16k, отправка работает. Если сумма превышает 16 КБ только на один байт, вторая отправка не удалась.
Похоже, какой-то внутренний буфер не перематывается, и вторая отправка пытается добавить данные в тот же буфер.
Обратите внимание. Это не Spring Boot. Это класс Java11 java.net.http.WebSocket.
Официальная документация метода отправки
Изменить:
Создан простой тест для отправки фиктивных данных
ByteBuffer bbuf1 = ByteBuffer.wrap((новый байт[15 * 1024]); ByteBuffer bbuf2 = ByteBuffer.wrap(новый байт[1024]); ws.sendBinary(bbuf1, false).join(); ws.sendBinary(bbuf2, true).join(); Это работает, если второй буфер равен 1024. Когда я увеличиваю второй буфер на 1, отправка завершается неудачей.
Я пришел к выводу, что отправка не удастся, если сумма размеров двух сообщений превышает 16 КБ. Серверная сторона объединяет фрагменты, пока не получит последний сегмент.
Мое клиентское приложение Java отправляет данные на сервер через WebSocket. В некоторых редких случаях данные превышают 16 тыс. Код разбивает данные на сегменты и отправляет их один за другим с помощью метода
ws.sendBinary(segmentMessageData, false).join();.
При отправке последнего сегмента второй аргумент имеет значение true. Отправлен первый сегмент 16 тыс. Когда отправляется второй (последний) сегмент, я получаю сообщение об ошибке:
СЕРЬЕЗНЫЙ: WebSocketClientPeer#onClose statusCode [1009], причина [Нет поддержки асинхронных сообщений и слишком маленький буфер. Размер буфера: [16 384], Размер сообщения: [1 656]] Как видите, буфер значительно больше данных. WebSocket открывается с помощью компоновщика
import java.net.http.WebSocket; // ... WebSocket.Builder wsBuilder = HttpClient.newHttpClient().newWebSocketBuilder(); ws = wsBuilder.buildAsync(URI.create("wss://myserver.dummy.com/wsweb"), this).join(); Клиентский код использует веб-сокет Java 11. Серверная часть использует Tomcat WebSocket. Сервер прекрасно отправляет данные размером более 16 КБ, а Java-клиент получает их (и объединяет в один пакет).
Это устаревшее приложение, в котором сервер находится в облаке и используется WebSocket. Существует реализация, которая использует собственный клиент Windows C++, и она работает нормально. Нам нужен независимый от платформы клиент.
Как отправить более 16 тыс. данных с помощью Java 11 WebSocket?
Обратите внимание: отправка работает нормально, если размер данных меньше 16 КБ и нет фрагментации.
Обнаружил странную вещь:
Если сумма двух сегментов i меньше или равна 16k, отправка работает. Если сумма превышает 16 КБ только на один байт, вторая отправка не удалась.
Похоже, какой-то внутренний буфер не перематывается, и вторая отправка пытается добавить данные в тот же буфер.
Обратите внимание. Это не Spring Boot. Это класс Java11 java.net.http.WebSocket.
Официальная документация метода отправки
Изменить:
Создан простой тест для отправки фиктивных данных
ByteBuffer bbuf1 = ByteBuffer.wrap((новый байт[15 * 1024]); ByteBuffer bbuf2 = ByteBuffer.wrap(новый байт[1024]); ws.sendBinary(bbuf1, false).join(); ws.sendBinary(bbuf2, true).join(); Это работает, если второй буфер равен 1024. Когда я увеличиваю второй буфер на 1, отправка завершается неудачей.
Я пришел к выводу, что отправка не удастся, если сумма размеров двух сообщений превышает 16 КБ. Серверная сторона объединяет фрагменты, пока не получит последний сегмент.
Мобильная версия