﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-皮杜妮-随笔分类-netty</title><link>http://www.blogjava.net/fanjs2000/category/54020.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 23 Nov 2013 07:57:05 GMT</lastBuildDate><pubDate>Sat, 23 Nov 2013 07:57:05 GMT</pubDate><ttl>60</ttl><item><title>netty高性能http服务</title><link>http://www.blogjava.net/fanjs2000/archive/2013/11/23/406722.html</link><dc:creator>猪眼睛</dc:creator><author>猪眼睛</author><pubDate>Sat, 23 Nov 2013 07:54:00 GMT</pubDate><guid>http://www.blogjava.net/fanjs2000/archive/2013/11/23/406722.html</guid><description><![CDATA[netty是一套高性能的通讯架构，这里我用netty实现http服务器实现信息采集功能。主要是利用他现有的hander处理器，解析出request头，做信息采集使用，重写了他自己的hander.<br /><br /><br /><div>package io.netty.example.http.snoop;<br /><br />import static io.netty.handler.codec.http.HttpHeaders.getHost;<br />import static io.netty.handler.codec.http.HttpHeaders.isKeepAlive;<br />import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION;<br />import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;<br />import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;<br />import static io.netty.handler.codec.http.HttpHeaders.Names.COOKIE;<br />import static io.netty.handler.codec.http.HttpHeaders.Names.SET_COOKIE;<br />import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;<br />import static io.netty.handler.codec.http.HttpResponseStatus.OK;<br />import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;<br /><br />import java.util.List;<br />import java.util.Map;<br />import java.util.Set;<br />import java.util.Map.Entry;<br /><br />import io.netty.buffer.ByteBuf;<br />import io.netty.buffer.Unpooled;<br />import io.netty.channel.ChannelHandlerContext;<br />import io.netty.channel.SimpleChannelInboundHandler;<br />import io.netty.handler.codec.http.Cookie;<br />import io.netty.handler.codec.http.CookieDecoder;<br />import io.netty.handler.codec.http.DefaultFullHttpResponse;<br />import io.netty.handler.codec.http.FullHttpResponse;<br />import io.netty.handler.codec.http.HttpContent;<br />import io.netty.handler.codec.http.HttpHeaders;<br />import io.netty.handler.codec.http.HttpObject;<br />import io.netty.handler.codec.http.HttpRequest;<br />import io.netty.handler.codec.http.LastHttpContent;<br />import io.netty.handler.codec.http.QueryStringDecoder;<br />import io.netty.handler.codec.http.ServerCookieEncoder;<br />import io.netty.util.CharsetUtil;<br /><br />public class HttpSnoopServiceTxt extends SimpleChannelInboundHandler&lt;Object&gt; {<br /><br />&nbsp;&nbsp; &nbsp;private HttpRequest request;<br />&nbsp;&nbsp; &nbsp;/** Buffer that stores the response content */<br />&nbsp;&nbsp; &nbsp;private final StringBuilder buf = new StringBuilder();<br /><br />&nbsp;&nbsp; &nbsp;@Override<br />&nbsp;&nbsp; &nbsp;protected void channelRead0(ChannelHandlerContext ctx, Object msg)<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;throws Exception {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// TODO Auto-generated method stub<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (msg instanceof HttpRequest) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;HttpRequest request = this.request = (HttpRequest) msg;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;buf.setLength(0);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// hostname<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;buf.append("HOSTNAME:").append(getHost(request, "unknown"));<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// url<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;buf.append("REQUEST_URI:").append(request.getUri());<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;// parm<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri());<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Map&lt;String, List&lt;String&gt;&gt; params = queryStringDecoder.parameters();<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (!params.isEmpty()) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for (Entry&lt;String, List&lt;String&gt;&gt; p : params.entrySet()) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String key = p.getKey();<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;List&lt;String&gt; vals = p.getValue();<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for (String val : vals) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;buf.append("PARAM:").append(key).append("=")<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;.append(val);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//cookie<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (msg instanceof HttpContent) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (msg instanceof LastHttpContent) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;LastHttpContent trailer = (LastHttpContent) msg;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;writeResponse(trailer, ctx);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;WriterFile.printtxt(buf.toString());<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;}<br /><br />&nbsp;&nbsp; &nbsp;@Override<br />&nbsp;&nbsp; &nbsp;public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ctx.flush();<br />&nbsp;&nbsp; &nbsp;}<br /><br />&nbsp;&nbsp; &nbsp;private boolean writeResponse(HttpObject currentObj,ChannelHandlerContext ctx) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;boolean keepAlive = isKeepAlive(request);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1,<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;currentObj.getDecoderResult().isSuccess() ? OK : BAD_REQUEST,<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Unpooled.copiedBuffer(buf.toString(), CharsetUtil.UTF_8));<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (keepAlive) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;response.headers().set(CONTENT_LENGTH,<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;response.content().readableBytes());<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ctx.write(response);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return keepAlive;<br />&nbsp;&nbsp; &nbsp;}<br /><br />}<br /><br /><br /><div>/*<br />&nbsp;* Copyright 2012 The Netty Project<br />&nbsp;*<br />&nbsp;* The Netty Project licenses this file to you under the Apache License,<br />&nbsp;* version 2.0 (the "License"); you may not use this file except in compliance<br />&nbsp;* with the License. You may obtain a copy of the License at:<br />&nbsp;*<br />&nbsp;*&nbsp;&nbsp; http://www.apache.org/licenses/LICENSE-2.0<br />&nbsp;*<br />&nbsp;* Unless required by applicable law or agreed to in writing, software<br />&nbsp;* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT<br />&nbsp;* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the<br />&nbsp;* License for the specific language governing permissions and limitations<br />&nbsp;* under the License.<br />&nbsp;*/<br />package io.netty.example.http.snoop;<br /><br />import io.netty.bootstrap.ServerBootstrap;<br />import io.netty.channel.Channel;<br />import io.netty.channel.EventLoopGroup;<br />import io.netty.channel.nio.NioEventLoopGroup;<br />import io.netty.channel.socket.nio.NioServerSocketChannel;<br /><br />/**<br />&nbsp;* An HTTP server that sends back the content of the received HTTP request<br />&nbsp;* in a pretty plaintext form.<br />&nbsp;*/<br />public class HttpSnoopServer {<br /><br />&nbsp;&nbsp;&nbsp; private final int port;<br /><br />&nbsp;&nbsp;&nbsp; public HttpSnoopServer(int port) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.port = port;<br />&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; public void run() throws Exception {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Configure the server.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EventLoopGroup bossGroup = new NioEventLoopGroup();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EventLoopGroup workerGroup = new NioEventLoopGroup();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServerBootstrap b = new ServerBootstrap();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b.group(bossGroup, workerGroup)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .channel(NioServerSocketChannel.class)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .childHandler(new HttpSnoopServerInitializer());<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Channel ch = b.bind(port).sync().channel();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ch.closeFuture().sync();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bossGroup.shutdownGracefully();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; workerGroup.shutdownGracefully();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int port;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (args.length &gt; 0) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port = 8080;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port = 8080;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new HttpSnoopServer(port).run();<br />&nbsp;&nbsp;&nbsp; }<br />}</div><div>/*<br />&nbsp;* Copyright 2012 The Netty Project<br />&nbsp;*<br />&nbsp;* The Netty Project licenses this file to you under the Apache License,<br />&nbsp;* version 2.0 (the "License"); you may not use this file except in compliance<br />&nbsp;* with the License. You may obtain a copy of the License at:<br />&nbsp;*<br />&nbsp;*&nbsp;&nbsp; http://www.apache.org/licenses/LICENSE-2.0<br />&nbsp;*<br />&nbsp;* Unless required by applicable law or agreed to in writing, software<br />&nbsp;* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT<br />&nbsp;* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the<br />&nbsp;* License for the specific language governing permissions and limitations<br />&nbsp;* under the License.<br />&nbsp;*/<br />package io.netty.example.http.snoop;<br /><br />import io.netty.channel.ChannelInitializer;<br />import io.netty.channel.ChannelPipeline;<br />import io.netty.channel.socket.SocketChannel;<br />import io.netty.handler.codec.http.HttpRequestDecoder;<br />import io.netty.handler.codec.http.HttpResponseEncoder;<br /><br />public class HttpSnoopServerInitializer extends ChannelInitializer&lt;SocketChannel&gt; {<br />&nbsp;&nbsp;&nbsp; @Override<br />&nbsp;&nbsp;&nbsp; public void initChannel(SocketChannel ch) throws Exception {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create a default pipeline implementation.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ChannelPipeline p = ch.pipeline();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Uncomment the following line if you want HTTPS<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //engine.setUseClientMode(false);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //p.addLast("ssl", new SslHandler(engine));<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p.addLast("decoder", new HttpRequestDecoder());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Uncomment the following line if you don't want to handle HttpChunks.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //p.addLast("aggregator", new HttpObjectAggregator(1048576));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p.addLast("encoder", new HttpResponseEncoder());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Remove the following line if you don't want automatic content compression.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //p.addLast("deflater", new HttpContentCompressor());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p.addLast("handler", new HttpSnoopServiceTxt());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //p.addLast("handler", new HttpSnoopServerHandler());<br />&nbsp;&nbsp;&nbsp; }<br />}</div></div><img src ="http://www.blogjava.net/fanjs2000/aggbug/406722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/fanjs2000/" target="_blank">猪眼睛</a> 2013-11-23 15:54 <a href="http://www.blogjava.net/fanjs2000/archive/2013/11/23/406722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>