Пользовательская реализация Netty ServerChannel - PullRequest
1 голос
/ 24 января 2012

У меня есть две системы, которые я хотел бы интегрировать, одна из которых использует полностью собственный сетевой стек, а другая (в частности, Flazr), использующая Netty. Я хочу прокси-поток потока RTMP на базе Flazr Netty через наш собственный стек HTTP, чтобы получить систему, которая говорит на RTMPT.

Для этого мне нужен объект Netty, который действует как сокет, но позволяет самому выполнять все «низкоуровневые» вещи - в основном просто оборачивая данные в HTTP и передавая их в наш собственный сетевой стек. Другими словами, я не хочу, чтобы Netty управляла какими-либо сокетами для меня - я хочу вставить свои собственные вещи между сокетом и Netty.

Я подозреваю, что правильный путь для этого - расширить AbstractServerChannel и создать класс * Factory, но я не уверен относительно того, как остальная часть Netty ожидает, что данные будут проходить через ServerChannel.

Мой собственный ServerChannel должен иметь возможность:

  • Уведомить Netty о подключении нового клиента через нашу существующую систему HTTP

  • Отправка данных в Netty, когда они поступят

  • Опрос новых сообщений от Netty, по запросу клиента

  • Очистить состояние Netty, когда истекает время сеанса HTTP (или поток RTMP закрыт чисто)

Есть какие-нибудь указатели на то, как должны быть реализованы ServerChannel, ServerChannelFactory? Я нашел, что javadocs довольно не хватает в этой области.

Некоторые конкретные вопросы:

  • Как моя реализация должна реагировать на вещи типа "InterestOps"?

  • Является ли ServerChannel.write тем, что вызывается для сообщений, которые попадают в стек? Что случилось с двумя разными перегрузками?

  • Как мне реализовать ServerChannel. (Dis) connect?

  • Должен ли я все это делать через ServerBootstrap или это слишком высокий уровень для этого?

Спасибо!

Прежде чем кто-либо спросит: ДА, я бы хотел заменить наш собственный сетевой стек на стек Netty, но это большая инженерная задача, которую мне было бы трудно оправдать. Детские шаги.

1 Ответ

10 голосов
/ 26 января 2012

Похоже, вы пытаетесь реализовать новый асинхронный транспорт, поэтому стоит взглянуть на NIO TCP транспорт (кроме дейтаграмм классов).

Я не уверен, насколько это уместно, но это поможет понять, как написать новую транспортную службу для Netty (поскольку вы спрашивали о сервере, клиентских каналах, фабриках и т. Д.)

Будет проще, если вы сможете понять модель событий Netty и как она проходит через конвейер. Это мое понимание того, как это работает.

  • События в восходящем направлении (события из сети) начинаются с Channel / ServerChannel, Boss / NioWorker и отправляются через конвейер, пока не достигнет последнего обработчика.

  • События в нисходящем направлении начинаются с последнего обработчика в нисходящем направлении и отправляются через конвейер и отправляются в ChannelSink, приемник каналов обрабатывает события и предпринимает действия или помещает сообщения в очереди канала.

Более подробно, (я полагаю, кто-то ищет транспортные классы Nio TCP, чтобы написать свой собственный транспорт для Netty).

NioWorker - При событиях селектора для каналов (все NioClientSocketChannel, NioAcceptedSocketChannel) запускает цикл nio - Данные, полученные из сети: получено сообщение о пожаре - Опрос записи очереди и делает неблокирующую запись - Опросить очередь задач на наличие интересующих оп событий и принять приостановку / возобновление канала?.

Boss

  • Запускает цикл событий сервера NIO.
  • Принять сокет клиента, создать NioAcceptedSocketChannel и зарегистрировать селекторы для NioWorker

NioClientSocketPipelineSink

  • Имеет исполнителя пула рабочих потоков.
  • Отправка исполняемых файлов NioWorker в пул рабочих потоков в конструкторе.
  • Здесь происходят нисходящие события клиентского канала и помещаются в каналы записи очереди / очереди задач, перехватывают некоторые события восходящего состояния и управляют состоянием канала.

NioServerSocketPipelineSink

  • Имеет пул потоков босса.
  • Передать исполняемые файлы Nio работника исполнителю при создании.
  • Отправить босс, работающий с ServerSocketChannel, исполнителю при событии связывания.
  • Здесь находятся нисходящие события канала сервера, которые перехватывают некоторые события восходящего состояния и управляют состоянием ServerSocketChannel.

Как моя реализация должна реагировать на вещи типа "InterestOps"?

Это зависит от характера канала (блокирующий / неблокирующий) и ограничений.

Является ли ServerChannel.write тем, что вызывается для сообщений, которые попадают в стек? Что случилось с двумя разными перегрузками?

Канал сервера не нуждается в поддержке этих вызовов методов, я думаю, вы имеете в виду канал

ChannelFuture write(Object message);

ChannelFuture write(Object message, SocketAddress remoteAddress);

Эти методы существуют для транспорта без установления соединения. Для TCP оба фактически делают одно и то же.

Как мне реализовать ServerChannel. (Dis) connect?

Канал сервера не должен поддерживать эти вызовы методов, но вы должны реализовать здесь bind и unbind.

Должен ли я делать все это через ServerBootstrap, или это слишком высокий уровень для этого материала?

Сервер / клиентские загрузчики - это просто вспомогательные классы для управления ресурсами конвейера и обеспечения фасада для привязки, подключения и отключения. Вы должны реализовать большую часть логики в

Клиент, серверный канал Impls
Клиентские, серверные конвейерные приемники
Босс, Рабочие классы,

Затем вы должны реализовать фабрики клиент-серверных каналов, используя вышеуказанные классы, если все это сделано, вы можете просто настроить сервер и клиент с помощью классов Bootstrap.

...