Java Netty-如何在一台服务器上正确地为web套接字和原始tcp提供服务?

Java Netty-如何在一台服务器上正确地为web套接字和原始tcp提供服务?,java,websocket,netty,socket.io,Java,Websocket,Netty,Socket.io,我想使用netty的一个实例为web套接字(socketio)和原始tcp连接提供服务。我现在要做的是在开始时只有一个RoutingHandler,它检查第一个字节,如果是“[”,则删除RoutingHandler并将tcp处理程序添加到通道管道,否则,添加web套接字处理程序。代码如下所示: public class RoutingHandler extends SimpleChannelInboundHandler<ByteBuf> { private final Se

我想使用netty的一个实例为web套接字(socketio)和原始tcp连接提供服务。我现在要做的是在开始时只有一个RoutingHandler,它检查第一个字节,如果是“[”,则删除RoutingHandler并将tcp处理程序添加到通道管道,否则,添加web套接字处理程序。代码如下所示:

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

    }

}
公共类RoutingHandler扩展了SimpleChannelInboundHandler{
私有上下文上下文;
公共路由句柄(最终服务器上下文){
this.context=上下文;
}
@凌驾
受保护的无效channelRead0(最终ChannelHandlerContext ctx,最终ByteBuf in)引发异常{
如果(在.isReadable()中){
ctx.pipeline().移除(此);
final byte firstByte=in.readByte();
in.readerIndex(0);
if(firstByte==0x5B){
this.context.routeChannelToTcp(ctx.channel());
}否则{
//网袋
this.context.routeChannelToSocketIO(ctx.channel());
}
ctx.pipeline().fireChannelActive();
最终字节[]副本=新字节[in.readableBytes()];
in.readBytes(副本);
ctx.pipeline().fireChannelRead(unmooled.wrappedBuffer(copy));
}
}
}
代码似乎可以正常工作,但似乎不是最好的方法,尤其是我通过手动调用fireChannelActive()来破解通道生命周期,因为添加额外的处理程序不会再次触发活动事件,因此某些初始化代码不会运行

我的解决方案有什么问题吗?有什么更好的方法?
这被称为端口统一,这是一个很好的例子,虽然它演示了TCP和HTTP(使用SSL和/或GZip检测)之间的切换,而不是WebSocket,但原理是相同的

基本上,您将读入前5个字节来嗅探协议(大致与您所做的相同),当协议被识别时,相应地修改管道中的处理程序


由于您无论如何都需要通过HTTP启动websocket,如果您添加了示例中所述的websocket升级过程,则该示例应该适用于您。

要了解这一点,请查看以下内容,这与Nicholas answer中提到的方法大致相同。
实现这一点的相关文件是和。

@user3444626-您是否成功地统一了http和socketio-我假设您使用mrniko/netty socketio?如果是,是否有说明这一点的代码片段?