如何使用 Netty 连接到运行 HTTP 服务器的 UNIX 域套接字? [英] How do I connect to a UNIX domain socket running an HTTP server using Netty?

查看:107
本文介绍了如何使用 Netty 连接到运行 HTTP 服务器的 UNIX 域套接字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Netty 连接到 Docker UNIX 域套接字.到目前为止,这是我的尝试.

I am trying to connect to a Docker UNIX domain socket using Netty. Here's my attempt so far.

@PostConstruct
public void init() throws Exception {
    io.netty.bootstrap.Bootstrap bootstrap = new io.netty.bootstrap.Bootstrap();
    bootstrap
            .group(new NioEventLoopGroup())
            .channel(NioSocketChannel.class)
            .option(ChannelOption.SO_KEEPALIVE, true)
            .remoteAddress(new DomainSocketAddress("/var/run/docker.sock"))
    .handler(new ChannelInitializer<SocketChannel>() {
        @Override
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            socketChannel
                    .pipeline()
                    .addLast(new SimpleChannelInboundHandler<HttpObject>() {
                        @Override
                        protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
                            System.out.println(httpObject);
                        }
                    });
        }
    });
    final Channel channel = bootstrap.connect().sync().channel();

    final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/services", Unpooled.EMPTY_BUFFER);
    request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
    channel.writeAndFlush(request);
    channel.closeFuture().sync();
    System.out.println("DONE");
}

目前我得到了

引起:java.nio.channels.UnsupportedAddressTypeException:null

Caused by: java.nio.channels.UnsupportedAddressTypeException: null

是否有关于如何使用 Netty 与 UDS 建立 HTTP 连接的示例?到目前为止,我只找到了原始 UDS 和 TCP HTTP,但没有合并.

Is there an example on how to do HTTP connections to UDS using Netty? So far I only found raw UDS and TCP HTTP but not combined.

推荐答案

这是一个有效的实现.

        io.netty.bootstrap.Bootstrap bootstrap = new io.netty.bootstrap.Bootstrap();
        final EpollEventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup();
        try {
            bootstrap
                    .group(epollEventLoopGroup)
                    .channel(EpollDomainSocketChannel.class)
                    .handler(new ChannelInitializer<UnixChannel>() {
                        @Override
                        public void initChannel(UnixChannel ch) throws Exception {
                            ch
                                    .pipeline()
                                    .addLast(new HttpClientCodec())
                                    .addLast(new HttpContentDecompressor())
                                    .addLast(new SimpleChannelInboundHandler<HttpObject>() {
                                        private StringBuilder messageBuilder = new StringBuilder();
                                        @Override
                                        public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
                                            if (msg instanceof HttpContent) {
                                                HttpContent content = (HttpContent) msg;
                                                messageBuilder.append(content.content().toString(StandardCharsets.UTF_8));
                                                if (msg instanceof LastHttpContent) {
                                                    System.out.println(messageBuilder);
                                                }
                                            } else {
                                                System.out.println(msg.getClass());
                                            }
                                        }
                                    });
                        }
                    });
            final Channel channel = bootstrap.connect(new DomainSocketAddress("/var/run/docker.sock")).sync().channel();

            final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/services", Unpooled.EMPTY_BUFFER);
            request.headers().set(HttpHeaderNames.HOST, "daemon");
            channel.writeAndFlush(request);
            channel.closeFuture().sync();
        } finally {
            epollEventLoopGroup.shutdownGracefully();
        }

注意事项:

  • EpollEventLoopGroupEpollDomainSocketChannelChannelInitializer 一起使用.
  • HTTP 需要管道中的 new HttpCodec() 才能使用 Netty HTTP 对象.
  • 数据可能被分块,因此您需要组合它并等待 LastHttpContent 对象
  • Use the EpollEventLoopGroup and EpollDomainSocketChannel with a ChannelInitializer<UnixChannel>.
  • HTTP requires new HttpCodec() in the pipeline to use the Netty HTTP objects.
  • The data may be chunked so you need to assemble it and wait for the LastHttpContent object

https://github.com/trajano/netty-docker-daemon-socket

这篇关于如何使用 Netty 连接到运行 HTTP 服务器的 UNIX 域套接字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆