Как отправить ответ обратно через установленное TCP-соединение в асинхронном режиме, используя Apache Camel Netty4? - PullRequest
0 голосов
/ 26 апреля 2018

Я создаю микро-сервис, который имеет маршрут Apache Camel, используя Netty4 Component (http://camel.apache.org/netty4.html) в режиме потребителя. Итак, в моем микро-сервисе этот маршрут, который я создаю, будет получать сообщения через TCP-соединение. Для этого я сделал это:

@Override
public void configure() throws Exception {
 this.from("netty4:tcp://localhost:7000?textline=true&encoding=utf8")
   .process(new Processor() {
      @Override
      public void process(final Exchange exchange) throws Exception {
        log.info("[Processor] - Incoming Message -> {}", exchange.getIn().getBody(String.class));
      }
   }).to("bean:messageService");
}

Ну, Я обычно получаю сообщения . Для тестирования я использую telnet:

$ telnet localhost 7000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
TheMessage

Проблема в том, что я хочу отправить сообщение обратно на тот же канал TCP, установленный на этом маршруте. В синхронном режиме я могу легко это сделать с помощью объекта Exchange. Однако в асинхронном режиме я не знаю, как отправить сообщение производителю.

Служба Spring, которая получает и должна отправлять сообщения, выглядит так:

@Service
public class MessageService {

  private static final Logger log = LoggerFactory.getLogger(MessageService.class);

  private List<String> messageStore = new LinkedList<>();

  public void sendToTCP(final String message) {
    log.info("[Service] - Sending Message over TCP Channel --> {}", message);
  }

  @Handler
  public void receiveFromTCP(final Exchange exchange) {
    final String messageFromTcp = exchange.getIn().getBody(String.class);
    log.info("[Service] - Message Received from TCP Channel --> {}", messageFromTcp);
    this.messageStore.add(messageFromTcp);
  }

  public List<String> getReceivedMessages() {
    return messageStore;
  }
}

В резюме мне нужно добавить код в этот метод, что-то вроде этого:

public void sendToTCP(final String message) {
  log.info("[Service] - Sending Message over TCP Channel --> {}", message);
  // Send message to producer here
  camelContext.createProducerTemplate.send....
}

Я не могу создать другой маршрут к производителю, потому что я не знаю IP производителя. Мне действительно нужно использовать уже установленный канал TCP между производителем и моим приложением. Связь должна быть через TCP, другие инструменты, такие как очереди, не являются опцией.


Пример проекта GitHub

Я загрузил пример проекта на GitHub: https://github.com/rgiaviti/so-camel-netty4-tcp

Draw

This is the draw of the communication TCP communication

Я использую:

  • Spring Boot 1.5.12;
  • Apache Camel 2.21.0;

1 Ответ

0 голосов
/ 22 августа 2018

Нашел решение на основе комментария @ vikram-palakurthi.

Я использовал свойство retyChannel Netty4. Код решения близок к этому:

  private static final Logger log = LoggerFactory.getLogger(MessageService.class);

  private List<String> messageStore = new LinkedList<>();
  private Channel openedChannel;

  public void sendToTCP(final String message) {
    log.info("[Service] - Sending Message over TCP Channel --> {}", message);
    log.info("[Service] - Channel is Active? {}", this.openedChannel.isActive());
    log.info("[Service] - Channel is Open? {}", this.openedChannel.isOpen());
    log.info("[Service] - Channel is Writeble? {}", this.openedChannel.isWritable());

    this.openedChannel.write(message);
    this.openedChannel.flush();
  }

  @Handler
  public void receiveFromTCP(final Exchange exchange) {
    this.openedChannel = exchange.getProperty(NettyConstants.NETTY_CHANNEL, Channel.class);
    final String messageFromTcp = exchange.getIn().getBody(String.class);
    log.info("[Service] - Message Received from TCP Channel --> {}", messageFromTcp);
    this.messageStore.add(messageFromTcp);
  }

Верблюжий раствор

Полное решение с Camel Routes, Processor ... можно найти здесь: https://github.com/rgiaviti/so-camel-netty4-tcp/tree/solution

Однако нам нужно знать, что это простое решение. Разработчику по-прежнему необходимо обрабатывать несколько каналов, закрывать каналы по производителю, проверять каналы ...

Vertx Solution

Я тоже разработал решение Vertx. https://github.com/rgiaviti/so-camel-netty4-tcp/tree/vertx-solution

...