当前位置: 首页 > 知识库问答 >
问题:

如何用netty客户端获取服务器响应

寿意远
2023-03-14
public class Client {
public static void main(String[] args) throws InterruptedException {
    Client client = new Client();

}

private Channel channel;

public Client() throws InterruptedException {
    EventLoopGroup loopGroup = new NioEventLoopGroup();

    Bootstrap b = new Bootstrap();
    b.group(loopGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(new StringDecoder()).
                    addLast(new StringEncoder()).
                    addLast(new ClientHandler());
        }
    });
    channel = b.connect("localhost", 9091).sync().channel();
}

public String sendMessage(String msg) {
    channel.writeAndFlush(msg);
    return ??????????;
}

在调用writeAndFlush()之后,我不知道如何从服务器检索响应;我该怎么办?

我也使用Netty 4.0.18.final

共有1个答案

宓跃
2023-03-14

为该方法返回future 很简单,我们将实现以下方法签名:

public Futute<String> sendMessage(String msg) {

当您了解异步编程结构时,这样做相对容易。为了解决设计问题,我们将执行以下步骤:

>

  • 写入消息时,将promise 添加到ArrayBlockingQueue

    这将作为最近发送的消息的列表,并允许我们更改未来 对象返回结果。

    当消息返回到处理程序时,根据队列的头部解析它

    这让我们得到正确的未来去改变。

    我们调用promise.setsuccess()来最终设置对象的状态,这将传播回未来的对象

    public class ClientHandler extends SimpleChannelInboundHandler<String> {
        private ChannelHandlerContext ctx;
        private BlockingQueue<Promise<String>> messageList = new ArrayBlockingQueue<>(16);
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            super.channelActive(ctx);
            this.ctx = ctx;
        }
    
        @Override
        public void channelInactive(ChannelHandlerContext ctx) {
            super.channelInactive(ctx);
            synchronized(this){
                Promise<String> prom;
                while((prom = messageList.poll()) != null) 
                    prom.setFailure(new IOException("Connection lost"));
                messageList = null;
            }
        }
    
        public Future<String> sendMessage(String message) {
            if(ctx == null) 
                throw new IllegalStateException();
            return sendMessage(message, ctx.executor().newPromise());
        }
    
        public Future<String> sendMessage(String message, Promise<String> prom) {
            synchronized(this){
                if(messageList == null) {
                    // Connection closed
                    prom.setFailure(new IllegalStateException());
                } else if(messageList.offer(prom)) { 
                    // Connection open and message accepted
                    ctx.writeAndFlush(message).addListener();
                } else { 
                    // Connection open and message rejected
                    prom.setFailure(new BufferOverflowException());
                }
                return prom;
            }
        }
        @Override
        protected void messageReceived(ChannelHandlerContext ctx, String msg) {
            synchronized(this){
                if(messageList != null) {
                     messageList.poll().setSuccess(msg);
                }
            }
        }
    }
    

    >

  • 专用ChannelHandlerContext CTX;

    用于存储对ChannelHandlerContext的引用,我们使用它来创建promise

    public void channelActive(ChannelHandlerContext ctx)

    当连接处于活动状态时由netty调用。在这里初始化变量。

    public void channelInactive(ChannelHandlerContext ctx)

    netty在由于错误或正常连接关闭而导致连接处于非活动状态时调用

    protected void messageReceed(ChannelHandlerContext ctx,String msg)

    当新消息到达时由netty调用,在这里选择队列的头部,然后对其调用setsuccess。

  •  类似资料:
    • 这是我关于StackOverflow的第一个问题,我希望我遵守了预期的标准。 我已经从不再在这里工作的其他人那里接管了一些代码,我几乎被困在这里。我搜索并询问了一些同事(不幸的是没有太多Java经验),但似乎没有人能帮助我。搜索也没有真正帮助我。 我正在从客户端向Netty服务器发送Json请求,故意不使用Netty实现。目前它只是一个简单的Java套接字,但其目的是让Flask客户端向Netty

    • 问题内容: 我经常在Netty工作,但仍然有一个概念在暗示我,在教程等中找不到任何内容。首先,我确实了解Netty是异步的,但是客户端必须有一种方法来调用服务器,并且能够获得处理程序之外的响应。让我解释更多。 我有一个客户,如下图所示。并且请注意,我知道它是自举的,并且在每次调用时都会建立一个新的连接,这是为了使示例更小,更简洁。请忽略这个事实。 客户端.java 现在,我了解了如何获取服务器上的

    • 我有一个Tcp客户端,连接到一个旧的主机(52年),发送和接收来自它的请求和响应。 这是我的客户机的核心连接部分, 我试图用Netty重写下面的文章。通过使用以下教程作为参考。 http://tutorials.jenkov.com/netty/netty-tcp-client.html 我面临的问题是我能够连接到服务器,但不能从中读写。我正在使用一个来执行读写操作。 这是我的脾气暴躁的客户 处理

    • 我将创建一个身份验证服务器,它本身与一组不同的Oauth2.0服务器交互。Netty似乎是在这里实现网络部分的一个很好的候选者。但在开始之前,我需要澄清一些关于netty的细节,因为我是新手。例行程序如下: > < li> 服务器接受来自客户端的HTTPS连接。 然后,不关闭第一个连接,它通过HTTPS与远程OAuth2.0服务器建立另一个连接并获取数据 毕竟,服务器将结果发送回客户端,客户端应该

    • 似乎服务器拒绝了wireshark输出中的tls协商,但我从代码中看不出原因。它是基于工作的代码,只是它被否决了,因此我用新的API更新。代码是开始。需要使用真实的证书。有人知道为什么服务器发送tcp FIN,ack吗? 我有以下服务器代码: 23 16.856111 sonymobi_7f:55:af intelcor_25:1d:fc ARP 42 10.1.10.100在84:c7:ea:7

    • 我需要在netty中有一个客户机/服务器通信,用于我的项目目的之一。所以我刚开始用一个handsOn来改进,我正在学习netty,我是一个初学者。 我尝试了一个简单的客户端服务器与Netty聊天。 客户端和服务器正在初始化,我可以看到服务器能够获得用于建立连接的客户端管道,但是当客户端发送消息时,它没有进入ServerAdapterHandler的messageReceived部分。下面是我的源代