【问题标题】:How do I connect to a UNIX domain socket running an HTTP server using Netty?如何使用 Netty 连接到运行 HTTP 服务器的 UNIX 域套接字?
【发布时间】:2020-02-15 17:26:46
【问题描述】:

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

@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

有没有关于如何使用 Netty 与 UDS 进行 HTTP 连接的示例?到目前为止,我只找到了原始 UDS 和 TCP HTTP,但没有找到组合。

【问题讨论】:

    标签: docker http netty unix-socket


    【解决方案1】:

    这是一个有效的实现。

            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&lt;UnixChannel&gt; 结合使用。
    • HTTP 需要管道中的 new HttpCodec() 才能使用 Netty HTTP 对象。
    • 数据可能被分块,因此您需要将其组装并等待LastHttpContent 对象

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-21
      • 1970-01-01
      • 2016-09-02
      • 2015-11-14
      • 2012-08-07
      • 2015-06-18
      相关资源
      最近更新 更多