У меня есть проблема синхронизации в отношении запроса привязки и обработчика восходящего потока, который принимает событие channelBound
. Мне нужно привязать объект к каналу, прежде чем обработчик сможет когда-либо получить событие channelBound
из-за того, что обработчик должен использовать объект для обработки обратного вызова. Пример ниже.Как присоединить объект к каналу, прежде чем обработчики получат события с Netty?
Handler пример:
public class MyClientHandler extends SimpleChannelUpstreamHandler {
@Override
public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e) {
/* Problem: This can occur while the channel attachment is still null. */
MyStatefulObject obj = e.getChannel().getAttachment();
/* Do important things with attachment. */
}
}
Основной пример:
ClientBootstrap bootstrap = ... //Assume this has been configured correctly.
ChannelFuture f = bootstrap.bind(new InetSocketAddress("192.168.0.15", 0));
/* It is possible the boundEvent has already been fired upstream
* by the IO thread when I get here.
*/
f.getChannel().setAttachment(new MyStatefulObject());
Возможные Soultions
Я придумал несколько решений, чтобы обойти эту проблему, но они оба вида «запаха», поэтому я здесь спрашиваю, есть ли у кого чистый способ сделать это.
Решение 1: Спин или блок в обратном вызове channelBound
до тех пор, пока вложение не будет равно нулю. Мне не нравится это решение, потому что он связывает работу с оператором ввода-вывода.
Решение 2: Сделайте MyClientHandler
в двунаправленный обработчик и получите вложение с помощью ThreadLocal
в обратном вызове bindRequested
. Мне это не нравится, потому что он полагается на деталь реализации Netty, что запрашивающий поток используется для запуска события bindRequested
.
Я нахожу решение 1 более терпимым, чем решение 2. Поэтому, если это то, что мне нужно сделать, я сделаю.
Есть ли простой способ получить ссылку на канал без запроса связывания или подключения в первую очередь?
Благодарим вас за ответ. Мне удалось решить проблему, используя ChannelFactory напрямую, как в вашем примере. – Dev
Кроме того, ваш первый пример демонстрирует ту же проблему синхронизации. После вызова 'bind' обратный вызов' channelBound' мог быть вызван до того, как слушатель присоединяется к будущему привязки. Опять же, как в моем первом комментарии, хотя ваш второй пример именно то, что мне нужно. – Dev
Согласен, извините за ошибку. Я удалил первый пример, чтобы не путать будущих зрителей :) –