Netty - 如何在客户端获取服务器响应

Ste*_*ier 10 java networking client-server netty

我主要在那里与Netty,但一个概念仍然暗指我,我在教程中找不到任何东西等等.首先,我确实理解Netty是异步的,但是必须有一种方法让客户端调用服务器并能够获得超出处理程序的响应.让我解释一下.

我有一个客户,如下图所示.请注意,我知道它是自助的,并且每次调用都建立了一个新连接,这就是为了使示例更小,更简洁.请忽略这一事实.

Client.java

// ServerResponse is a result from the server, in this case 
// a list of users of the system (ignore that each time it's all bootstrapped).

public User[] callServerForInformationFromGUIWidget()
{
    ClientBootstrap bootstrap = new ClientBootstrap(...);
    bootstrap.setPipelineFactory(...);

    ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
    Channel channel = future.awaitUninterruptibly().getChannel();

    // Where request is a POJO sent to the server, 
    // with a request such as get me a list of users
    RequestPojo request = new RequestPojo(requestUserListCommand);

    ChannelFuture lastWriteFuture = channel.write(request);

    if(lastWriteFuture != null)
        lastWriteFuture.awaitUninterruptibly();
}
Run Code Online (Sandbox Code Playgroud)

现在我了解如何获取服务器上的数据,并重新启动结果.唯一的问题是如何在客户端处理它?是的clientHandler类可以执行以下操作:

ClientHandler.java

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) 
{
    User[] users = (User[])e.getMessage();
}
Run Code Online (Sandbox Code Playgroud)

问题是客户端代码如何实际获得该结果?所有示例都类似于聊天服务,其中事件触发客户端上不等待响应的其他内容.甚至我发现的http客户端示例也缺乏这个.整体文档非常好,但缺乏如何进行回调.无论如何,在这种情况下,我需要客户端从服务器获取响应,并根据结果它将执行它所需的.

换句话说,我如何编写客户端来执行以下操作:

IdealClient.java

// ServerResponse is a result from the server, in this case 
// a list of users of the system.

public User[] callServerForInformationFromGUIWidget()
{
    ...
    RequestPojo request = new RequestPojo(requestUserListCommand);
    ChannelFuture lastWriteFuture = channel.write(request);

    if(lastWriteFuture != null)
        lastWriteFuture.awaitUninterruptibly();

    User[] users = resultFromCallToServer();

    performSomeAction(users);
}
Run Code Online (Sandbox Code Playgroud)

因为处理程序不知道谁在寻找答案,或者谁问了问题.如果它是在处理程序中完成的,那么如何?

回到我对这些示例的评论,http客户端(和处理程序)示例只是将结果转储到System.out.如果您有一个GUI,您如何将结果从您的请求传递到GUI?我从未见过这方面的任何例子.

bar*_*rdh 5

杰斯坦是对的.在我的情况下,我有一个客户需要处理价格刻度数据.我使用Antlr进行解析.我在我的解析器中激活了我的事件,但在我的情况下,我的协议是基于字符串的.下面是没有Antlr的示例,我在您的情况下传递String消息,它可能是用户.

//----------------- Event --------------
public class DataChangeEvent {
    private String message;

    public DataChangeEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }


}

//----------------- Listener --------------
public interface DataChangeListenter {
    public void dataChangeEvent(DataChangeEvent event);
}

//----------------- Event Handler that fires the dataChange events --------------
// This class needs to be static since you need to register all your classes that want to be notified of data change events
public class DataChangedHandler {
    private static List<DataChangeListenter> listeners = new ArrayList<DataChangeListenter>();

    public static void registerDataChangeListener(DataChangeListenter listener) {
        listeners.add(listener);
    }

    public static void fireDataChange(DataChangeEvent dataChangeEvent) {
        for(DataChangeListenter listenter : listeners) {
            listenter.dataChangeEvent(dataChangeEvent);
        }
    }
}

//----------------- Example class that implements the listener and registers itself for events --------------
public class ProcessMessage implements DataChangeListenter {

    public ProcessMessage() {
        DataChangedHandler.registerDataChangeListener(this);
    }

    public void dataChangeEvent(DataChangeEvent event) {
        //Depending on your protocal, I use Antlr to parse my message
        System.out.println(event.getMessage());
    }


}

//---------------- Netty Handler -----------
public class TelnetClientHandler extends SimpleChannelHandler {

    private static final Logger logger = Logger.getLogger(TelnetClientHandler.class.getName());

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
        String message = (String) e.getMessage();
        DataChangedHandler.fireDataChange(message);
    }
}
Run Code Online (Sandbox Code Playgroud)