Новички, испытывающие затруднения при обработке видеопотока UDP с использованием Netty 3.2.4.На разных машинах мы видим сброшенные байты и т.д., используя Netty.У нас есть небольшой счетчик после того, как Нетти вводит байты, чтобы увидеть, сколько байтов получено.Разница больше, чем то, что объясняется ненадежностью UDP.В нашем случае мы также сохраняем байты в файл для воспроизведения видео.Воспроизведение видео в VLC действительно иллюстрирует пропущенные байты.(Размеры отправляемых пакетов составляли около 1000 байт).
Вопросы
- Правильны ли наши предположения относительно API Netty с точки зрения невозможности использованияAdaptiveReceiveBufferSizePredictor для прослушивателя потока UDP?
- Есть ли лучшее объяснение поведения, которое мы наблюдаем?
- Есть ли лучшее решение?Есть ли способ использовать адаптивный предиктор с UDP?
Что мы попробовали
...
DatagramChannelFactory datagramChannelFactory = new OioDatagramChannelFactory(
Executors.newCachedThreadPool());
connectionlessBootstrap = new ConnectionlessBootstrap(datagramChannelFactory);
...
datagramChannel = (DatagramChannel) connectionlessBootstrap.bind(new
InetSocketAddress(multicastPort));
datagramChannel.getConfig().setReceiveBufferSizePredictor(new
FixedReceiveBufferSizePredictor(2*1024*1024));
...
Из документации иПоиски в Google, я думаю, правильный способ сделать это - использовать OioDatagramChannelFactory вместо NioDatagramChannelFactory.
Кроме того, хотя я не смог найти его заявленную детальность, вы можете использовать только FixedReceiveBufferSizePredictor с OioDatagramChannelFactory (против AdaptiveReceiveBufferSizePredictor).Мы выяснили это, посмотрев на исходный код и осознав, что метод предыдущегоReceiveBufferSize () AdaptiveReceiveBufferSizePredictor не вызывался из класса OioDatagramWorker (тогда как он вызывался из NioDatagramWorker)
Итак,Мы изначально установили FixedReceivedBufferSizePredictor в (2 *1024* 1024)
Наблюдаемое поведение
Работа на разных машинах (разная вычислительная мощность) мы видим, что Netty принимает другое количество байтов.В нашем случае мы транслируем видео через UDP и можем использовать воспроизведение потоковых байтов для диагностики качества считываемых байтов (Размеры отправляемых пакетов были около 1000 байтов).
Затем мы экспериментировали с различными размерами буфера и обнаружили, что 1024 * 1024, кажется, заставляет вещи работать лучше ... но на самом деле понятия не имею, почему.
Рассматривая, как FixedReceivedBufferSizePredictorработает, мы поняли, что он просто создает новый буфер каждый раз, когда приходит пакет. В нашем случае это создаст новый буфер размером 2 *1024* 1024 байта, независимо от того, был ли пакет 1000 байтов или 3 МБ.Наши пакеты были только 1000 байтов, поэтому мы не думали, что это наша проблема.Может ли какая-либо из этих логик вызывать проблемы с производительностью?Например, создание буфера каждый раз, когда приходит пакет?
Наш обходной путь
Затем мы подумали о том, как сделать размер буфера динамическим, но поняли, что не можем использовать AdaptiveReceiveBufferSizePredictor, как отмечено выше.Мы экспериментировали и создали наш собственный MyAdaptiveReceiveBufferSizePredictor вместе с сопровождающими классами MyOioDatagramChannelFactory, * Channel, * ChannelFactory, * PipelineSink, * Worker (которые в конечном итоге вызывают MyAdaptiveReceiveBufferSizePredictor).Предиктор просто меняет размер буфера, чтобы удвоить размер буфера на основе последнего размера пакета или уменьшить его.Это, казалось, улучшило ситуацию.