Netty 4.1.2动态管道变化

Netty 4.1.2动态管道变化,netty,pipeline,Netty,Pipeline,我目前正在基于netty的websocket服务器上工作。我试图实现一个登录功能,但我有一些问题。 我的初始化管道如下所示: pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new HttpObjectAggregator(65536)); pipeline.addLast(new WebSocketServerCompressionHandler()); pipeline.addLast(new WebSocketServer

我目前正在基于netty的websocket服务器上工作。我试图实现一个登录功能,但我有一些问题。 我的初始化管道如下所示:

pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
pipeline.addLast(new RequestHandler(WEBSOCKET_PATH));
pipeline.addLast("HandlerLogin", new FrameHandlerLogin());
成功登录后,FrameHandlerLogin应该更改管道,我认为这行代码可以完成这项工作,但没有任何更改:

ctx.pipeline().addLast("HandlerSQL", new FrameHandlerSQL());
ctx.pipeline().remove("HandlerLogin");
是否有失误或有其他工作要做

谢谢,谢尔

好的,更详细地说: 我主要使用netty提供的websocket示例。服务器以以下方式启动:

erverBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new PipelineInitializer(sslCtx));

        Channel ch = bootstrap.bind("localhost",PORT).sync().channel();

        System.out.println("Open your web browser and navigate to " + "https" + "://127.0.0.1:" + PORT + '/');

        ch.closeFuture().sync();
PipelineInitializer初始化上面列出的所有处理程序。运行应用程序并通过firefox连接没有问题。输入用户名和密码也可以。FramHandlerLogin执行以下操作:

protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception {
    String recievedUser;
    String recievedPsw;

    if (frame instanceof TextWebSocketFrame) {
        String request = ((TextWebSocketFrame) frame).text();
        JSONObject in = (JSONObject) JSONValue.parse(request);
        recievedUser = (String) in.get("user");
        recievedPsw = (String) in.get("psw");
        if (recievedUser.equals(USER) && recievedPsw.equals(PASSWORD)) {
            System.out.println("Recieved correct User and Password!");


            ctx.pipeline().addLast("HandlerSQL", new FrameHandlerSQL());
            ctx.pipeline().remove("HandlerLogin");

            ctx.channel().writeAndFlush(new TextWebSocketFrame("Success"));


        } else {
//some error handling
到目前为止还不错。如果收到“成功”,websocket将请求/sql.html

RequestHandler现在将uri和管道记录到控制台

protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
    // Handle a bad request.
    ...

    // Allow only GET methods.
    ...

//TODO Debug remove
//after a successfull client login, the requested uri should be sql.html
//also the pipeline should use the FrameHandlerSQL and not the FrameHandlerLogin. 
//The problem is, that the FrameHAndlerLogin is still active and the FrameHandlerSql is not
    System.out.println("URI:" + req.uri() );
    if(ctx.pipeline().get("HandlerLogin") != null){
        System.out.println("Piepline: Login" );
    } else if(ctx.pipeline().get("HandlerSQL") != null) {
        System.out.println("Piepline: SQL");
    }
    // Send the index page
    if ("/".equals(req.uri()) || "/index.html".equals(req.uri())) {
        String webSocketLocation = getWebSocketLocation(ctx.pipeline(), req, websocketPath);
        ByteBuf content = null;
        content = PageLoaderLogin.getContent(webSocketLocation);
        FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, content);
        res.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
        HttpUtil.setContentLength(res, content.readableBytes());
        sendHttpResponse(ctx, req, res);

} else if ("/sql.html".equals(req.uri())) {
        String webSocketLocation = getWebSocketLocation(ctx.pipeline(), req, websocketPath);
        ByteBuf content = null;
        content = PageLoaderSQL.getContent(webSocketLocation);
        FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, content);
        res.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
        HttpUtil.setContentLength(res, content.readableBytes());
        sendHttpResponse(ctx, req, res);
    } else {
        sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND));
    }
}
它表示登录成功,但下一个请求的piepline仍然是旧的,正如您在RequestHandler附近的注释中所看到的

所有请求的上下文是否相同?还是为每个请求都创建了一个新的上下文?我想这可能就是问题所在


谢尔

不,这就是你应该做的一切。。。什么不起作用?你如何知道它不起作用?请添加更多详细信息我编辑了上面的帖子。我仍然不明白你在哪里解释什么不起作用以及为什么你认为它不起作用。请重新编辑。但问题可能是,每次请求都会创建新的上下文,对吗?只要后续请求使用相同的SocketChannel实例,管道应该是相同的。