2016-03-01 3 views
1

Я пишу приложение JavaFX, используя Netty для реализации настраиваемого протокола. Нет состояния сеанса, но я хотел бы сопоставить ответ сервера с конкретным исходящим запросом (и вернуть результат в правильный JavaFX Task.) До сих пор я не смог сделать это в клиентском коде, потому что ответ Future это ChannelFuture<Void>.Обработка ответа от сервера в клиенте Netty

future = tcpBoostrap.connect(address, 3333).sync(); 
final Channel channel = future.awaitUninterruptibly().channel(); 

ChannelFuture responseFuture = channel.writeAndFlush(requestBuilder.build()); 
responseFuture.addListener(new ChannelFutureListener() { 
    @Override 
    public void operationComplete(ChannelFuture channelFuture) throws Exception { 
     if (channelFuture.isSuccess()) { 
      logger.debug("completed operation: {}", channelFuture.toString()); 
     } 
    } 
}); 

Я попытался глядя том, как настроить PipeLine каким-то образом установить ChannelHandlers, что бы поделиться информацией в общей переменной контекста, но я не мог найти что-нибудь существенное.

Может ли кто-нибудь предложить идиоматическое место, где я могу заполнить задачу пользовательского интерфейса, которую я могу «заполнить» ответом в Netty?

ответ

0

Netty не может делать такую ​​работу за вас, так как не может понять механизм сопряжения. На стороне клиента вам необходимо реализовать ChannelHandler и передать инициализатор методу .handler(handler). См. Netty TimeClient example. В обработчике channelRead метод обрабатывает ответ с сервера, десериализует его и в соответствии с механизмом, специфичным для вашей пары приложений, с ранее созданным Future и завершает его. Future не обязательно должен быть Netty будущего, поскольку эта часть полностью исключена из обработки Netty.

Для сопряжения Я предполагаю, что вы используете некоторый идентификатор, который вы отправляете на сервер, и сервер отправляет тот же идентификатор клиенту. Поэтому в таком случае достаточно Map<Long, Future<?>>.

+0

Итак, в основном что-то вроде [этого ответа] (http://stackoverflow.com/a/9048781/261984). Удерживайте конвейер, используемый в инициализаторе, и 'addLast' clientHandler, который содержит ссылку на задачу – Eddy

+0

@Eddy: Частично да, в том, как они создают обработчик. Но учтите, что обработчик создан для соединения (или может быть даже разделен), поэтому невозможно дать ему ссылку на Request/Future, если вы повторно используете одно и то же соединение для многих запросов. Вам необходимо сохранить карту идентификаторов запроса в SettableFuture или обратном вызове, которые вы затем завершите, получив соответствующий ответ. –

Смежные вопросы