Practical Netty (6) HTTP Server/Client Club兴趣俱乐部社区年轻人
程序员文章站
2022-05-10 10:15:18
...
Practical Netty (6) HTTP Server/Client
- 作者:柳大·Poechant(钟超)
- 邮箱:zhongchao.ustc#gmail.com(# -> @)
- 博客:Blog.CSDN.net/Poechant
- 微博:weibo.com/lauginhom
- 产品:Club http://whatsclub.cn
- 日期:June 18th, 2012
Netty 提供的 HTTP 功能,比较适合在 Netty 搭建的 TCP 或 UDP 服务器上做一些专用的 HTTP 服务,而非一般性的通用 HTTP 服务器。所以不要将 Netty 的自行实现的 HTTP 服务器的易用性与现有 Nginx、Lighttpd 等来比较。
1 HTTP Server
主要不同就是 Pipeline 用什么 handlers,以及我们自定义的 handler 如何处理 HttpRequest,并生成相应的 HttpResponse。
public class ServerPipelineFactory implements ChannelPipelineFactory {
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
pipeline.addLast("encoder", new HttpResponseEncoder());
pipeline.addLast("handler", new PoechantRequestHandler());
return pipeline;
}
}
如何接收 request?如何解析 request?如何产生 response?就看下面的 request handler。
public class PoechantRequestHandler extends SimpleChannelUpstreamHandler {
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
System.out.println("channel connected...");
super.channelConnected(ctx, e);
}
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
HttpRequest request = (HttpRequest) e.getMessage();
System.out.println(
"request length: " +
((HttpRequest) e.getMessage()).getContent().readableBytes());
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
response.setContent(ChannelBuffers.copiedBuffer("I'm a response", CharsetUtil.UTF_8));
response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
e.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);
}
}
在 Response 中 还可以设置其他的 Headers:
response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, 123);
response.setHeader("Content", "keep-alive");
还有一些 Headers 相关的 Name 和 Value,可以在HttpHeaders.Names
和HttpHeaders.Values
中找到。
2. HTTP Client
ClientBootstrap 一旦连接成功,就可以发送 HttpRequest 了,连接的代码实例如下:
Channel channel =
cb.connect(
new InetSocketAddress("10.0.0.110", 9980)).awaitUninterruptibly().getChannel();
如上是一个阻塞式的连接方式,在连接确认成功或失败前,会一直 block 在那里。异步的方式则如下:
ChannelFuture future = cb.connect(new InetSocketAddress("10.0.0.110", 9980));
Channel channel = future.getChannel();
然后就可以用这个 channel 发消息了。如果是异步的,则要监听成功之后再发送。
future.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception {
// send a request to the http server
}
});
然后就可以发送数据了。如果是异步的,
HttpRequest request =
new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/docs/index.html");
request.addHeader(HttpHeaders.Names.HOST, "10.0.0.110");
channel.write(request).awaitUninterruptibly().getChannel().getCloseFuture().awaitUninterruptibly();
当然你也可以异步发送。
channel.write(request);channel.write(request);
-
Club 产品官网:http://whatsclub.cn 年轻人的兴趣俱乐部(社区)
转载请注明来自柳大的CSDN博客:Blog.CSDN.net/Poechant,微博:weibo.com/lauginhom
-