Question

I want to use a single instance of netty to serve both web socket(socketio) and raw tcp connections. What i am doing now is to have ONLY a RoutingHandler at start which checks the first byte, if it is '[' , then remove the RoutingHandler and add tcp handlers to the channel pipeline, otherwise, add web socket handlers. The code looks like :

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));
        }

    }

}

The code seems to be working but it does not seem the best way to do it, especially I am kind of hacking the channel lifecycle by manually calling fireChannelActive() because adding extra handlers do not trigger the active event again hence some initialization code is not run.

IS there anything wrong with my solution? What is a better way to do it? Thanks

Was it helpful?

Solution

This is referred to as Port Unification. There is a good example of it here, although it demonstrates switching between TCP and HTTP (with SSL and/or GZip detection), and not websockets, but the principles are the same.

Basically, you will read in the first 5 bytes to sniff the protocol (more or less as you did) and when the protocol is identified, modify the handlers in the pipeline accordingly.

Since you need to initiate a websocket through HTTP anyway, the example should work for you if you add the websocket upgrade procedure as outlined in this example.

OTHER TIPS

To see this in action, take a look at the following game server which does this exactly. It is much the same way mentioned in Nicholas answer. The relevant files that will do this are ProtocolMux and LoginProtocol.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top