欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Practical Netty (6) HTTP Server/Client Club兴趣俱乐部社区年轻人 

程序员文章站 2022-05-10 10:15:18
...

Practical Netty (6) HTTP Server/Client


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.NamesHttpHeaders.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

-