Practical Netty (6) HTTP Server/Client

本文介绍了如何使用Netty实现HTTP服务器和客户端。Netty的HTTP功能适合搭建专用HTTP服务,而非通用服务器。文章详细讲解了HTTP服务器中Pipeline的配置、HttpRequest的处理和HttpResponse的生成。同时,还展示了HTTP客户端的连接和发送HttpRequest的方法,包括同步和异步两种方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);

-

转载请注明来自柳大的优快云博客:Blog.youkuaiyun.com/Poechant,微博:weibo.com/lauginhom

-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

钟超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值