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.
Официальная документация метода отправки
Изменить:
Создан простой тест для отправки фиктивных данных
импортировать java.net.URI; импортировать java.net.http.HttpClient; импортировать java.net.http.WebSocket; импортировать java.nio.ByteBuffer; WebSocket.Builder wsBuilder = HttpClient.newHttpClient().newWebSocketBuilder(); WebSocket ws = wsBuilder.buildAsync(URI.create("ws://127.0.0.1/wsendpoint"), this).join(); // Дождитесь завершения рукопожатия, затем отправьте данные 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.
Официальная документация метода отправки
Изменить:
Создан простой тест для отправки фиктивных данных
импортировать java.net.URI; импортировать java.net.http.HttpClient; импортировать java.net.http.WebSocket; импортировать java.nio.ByteBuffer; WebSocket.Builder wsBuilder = HttpClient.newHttpClient().newWebSocketBuilder(); WebSocket ws = wsBuilder.buildAsync(URI.create("ws://127.0.0.1/wsendpoint"), this).join(); // Дождитесь завершения рукопожатия, затем отправьте данные ByteBuffer bbuf1 = ByteBuffer.wrap(новый байт[15 * 1024]); ByteBuffer bbuf2 = ByteBuffer.wrap(новый байт[1024]); ws.sendBinary(bbuf1, false).join(); ws.sendBinary(bbuf2, true).join(); Это работает, если второй буфер равен 1024. Когда я увеличиваю второй буфер на 1, отправка завершается неудачей.
Я пришел к выводу, что отправка не удастся, если сумма размеров двух сообщений превышает 16 КБ. Фрагментация обязательна, поскольку сервер объединяет фрагменты и обрабатывает сообщение целиком.
Мобильная версия