我想处理两个不同的客户端。 一个是简单的tcp客户端,它发送字符串数据包。另一个是http客户端,它发送httprequest msg。我是Netty的初学者,我不知道管道中的处理程序如何流动。
这是我的服务器编码
公共类TCPServer {int port; public static void main(String[] args) { new TCPServer().start(); } public void start() { port = 1222; EventLoopGroup producer = new NioEventLoopGroup(); EventLoopGroup consumer = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap() .option(ChannelOption.SO_BACKLOG, 1024) .group(producer, consumer)//separate event loop groups to handle for parent and child for handling all chanel events .channel(NioServerSocketChannel.class)//select type of chanel .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ServerAdapterInitializer());//configure chanel pipeline System.out.println("Server started");// configuring server channel bootstrap.bind(port).sync().channel().closeFuture().sync();//start the server and Wait until the server socket is closed. Thread gets blocked. } catch (Exception e) { e.printStackTrace(); } finally { producer.shutdownGracefully(); consumer.shutdownGracefully(); } }
}
这是我的serverInitializer
公共类ServerAdapterInitializer扩展ChannelInitializer {//特殊的香奈儿处理程序配置已注册的香奈儿管道@Override受保护的void initChannel(SocketChannel channel)引发异常{//一旦注册了香奈儿,就会调用此方法ChannelPipeline管道= channel.pipeline();pipe.addLast(“ decoder”,new StringDecoder()); // chanel入站处理程序pipeline.addLast(“ encoder”,new StringEncoder());Pipeline.addLast(“ handler”,new TCPServerHandler());}}
这是我的处理程序,用于同时处理httprequest和字符串。但是我的处理程序从不处理httprequest数据包。
TCPServerHandler类扩展了SimpleChannelInboundHandler {私有静态最终字节[] CONTENT = {'H','e','l','l','o',','W','o','r','l','d '};私有静态最终ChannelGroup渠道=新的DefaultChannelGroup(“ tasks”,GlobalEventExecutor.INSTANCE);@Override公共无效channelRead0(ChannelHandlerContext ctx,对象msg)引发异常{if(msg instanceof HttpRequest){System.out.println(“ http request”);HttpRequest req =(HttpRequest)msg;boolean keepAlive = HttpUtil.isKeepAlive(req);FullHttpResponse response = new DefaultFullHttpResponse(req.protocolVersion(),OK,Unpooled.wrappedBuffer(CONTENT));response.headers().set(CONTENT_TYPE,TEXT_PLAIN).setInt(CONTENT_LENGTH,response.content()。visibleBytes());如果(keepAlive){如果(!req.protocolVersion()。isKeepAliveDefault()){response.headers()。set(CONNECTION,KEEP_ALIVE);}}其他{//告诉客户我们要关闭连接。response.headers()。set(CONNECTION,CLOSE);}ChannelFuture f = ctx.write(response);如果(!keepAlive){f.addListener(ChannelFutureListener.CLOSE);}}if(msg instanceof String){System.out.println(“ String request”);字符串arg1 =(String)msg;通道currentChannel = ctx.channel();if(arg1.equals(“ quit”)){System.out.println(“ [INFO]-” + currentChannel.remoteAddress()+“正在退出...”);}其他{System.out.println(“ [INFO]-” + currentChannel.remoteAddress()+“-” + arg1);currentChannel.writeAndFlush(“ Server Said Hii” + arg1);}}}}
我认为无法配置相同的服务器引导程序来处理HTTP请求和原始String消息。您需要两个服务器引导程序(一个用于HTTP,一个用于String消息),每个都有自己的管道。您已经具有用于String消息处理的解码器/编码器。
对于HTTP,您需要添加处理程序HttpServerCodec
和HttpObjectAggregator
,以便能够从通道读取FullHttpRequest
并将FullHttpResponse
写入通道。
(聚合器是可选的,它可以帮助您避免将分段的传入HTTP数据合并为单个(完整)HTTP请求以及将合并的(完整)HTTP响应写入通道的任务)
在服务器中:
ch.pipeline().addLast("httpcodec" , new HttpServerCodec());
ch.pipeline().addLast("httpaggregator", new HttpObjectAggregator(512 * 1024));
ch.pipeline().addLast("yourhandler" , new YourHttpRequestHandler());
FullHttpRequest
处理的示例处理程序:
public class YourHttpRequestHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg_arg)
{
FullHttpRequest msg = (FullHttpRequest)msg_arg;
System.out.println("URI: " + msg.getUri());
System.out.println("method: " + msg.getMethod().toString());
System.out.println("protocol version: " + msg.getProtocolVersion());
System.out.println("header1: " + msg.headers().get("header1"));
System.out.println("header2: " + msg.headers().get("header2"));
System.out.println("header3: " + msg.headers().get("header3"));
System.out.println("content: " + msg.content().toString(CharsetUtil.UTF_8));
}//end read
}//end handler