我目前在基于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");
是否存在错误或是否需要做一些额外的工作?
谢谢,Schere
确定如此详细: 我主要使用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初始化了上面列出的所有处理程序。 Runnig应用程序和通过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附近的评论中所见。
所有请求的上下文是否相同?或者是为每个请求创建的新上下文?我想这可能是问题?
Schere