Netty - Как правильно обслуживать веб-сокеты и raw tcp на одном сервере?

Я хочу использовать один экземпляр netty для обслуживания как веб-сокетов (socketio), так и необработанных TCP-соединений. Сейчас я хочу иметь ТОЛЬКО RoutingHandler в начале, который проверяет первый байт, если он равен '[', затем удаляю RoutingHandler и добавляю обработчики tcp в конвейер канала, в противном случае добавляю обработчики веб-сокетов. Код выглядит так:

public class RoutingHandler extends SimpleChannelInboundHandler<ByteBuf> {

    private final ServerContext context;

    public RoutingHandler(final ServerContext context) {

        this.context = context;
    }

    @Override
    protected void channelRead0(final ChannelHandlerContext ctx, final ByteBuf in) throws Exception {

        if (in.isReadable()) {

            ctx.pipeline().remove(this);

            final byte firstByte = in.readByte();
            in.readerIndex(0);
            if (firstByte == 0x5B) {

                this.context.routeChannelToTcp(ctx.channel());

            } else {
                // websocket

                this.context.routeChannelToSocketIO(ctx.channel());

            }

            ctx.pipeline().fireChannelActive();

            final byte[] copy = new byte[in.readableBytes()];
            in.readBytes(copy);

            ctx.pipeline().fireChannelRead(Unpooled.wrappedBuffer(copy));
        }

    }

}

Код, кажется, работает, но это не лучший способ сделать это, особенно я как бы взламываю жизненный цикл канала, вручную вызывая fireChannelActive (), потому что добавление дополнительных обработчиков не запускает активное событие снова, поэтому некоторый код инициализации не бег.

Что-то не так с моим решением? Как лучше это сделать? Спасибо


person user3444626    schedule 21.03.2014    source источник


Ответы (2)


Это называется объединением портов. Хороший пример этого здесь, хотя демонстрирует переключение между TCP и HTTP (с обнаружением SSL и / или GZip), а не веб-сокетами, но принципы те же.

По сути, вы будете читать первые 5 байтов, чтобы обнюхать протокол (более или менее, как вы), и когда протокол будет идентифицирован, соответствующим образом измените обработчики в конвейере.

Поскольку вам все равно нужно инициировать веб-сокет через HTTP, пример должен работать для вас, если вы добавите процедуру обновления веб-сокета, как описано в этот пример.

person Nicholas    schedule 21.03.2014
comment
@ user3444626 - удалось ли вам объединить http и socketio - я предполагаю, что вы используете mrniko / netty-socketio? если да, то есть ли где-нибудь фрагмент кода, иллюстрирующий это? - person Remigius Stalder; 04.05.2015

Чтобы увидеть это в действии, взгляните на следующий игровой сервер, который делает это именно так. Это примерно то же самое, что упоминается в ответе Николая. Соответствующие файлы, которые будут делать это: ProtocolMux и LoginProtocol.

person Abe    schedule 22.03.2014