2015-03-01 3 views
1

Когда я получаю одно сообщение от клиента неакки через TCP-сокет, мне нужно ответить как три сообщения. В следующем примере, приведенном ниже, только первый отправляется должным образом отправителю (клиент TCP, который не является AKKA). Остальные два идут к мертвой букве. Есть идеи? Заранее спасибо.Несколько сообщений отправляются в Akka-Scala-Camel-TCP Сокеты, которые собираются на мертвые буквы

object TcpExample { 
def main(args: Array[String]): Unit = { 
    val system = ActorSystem("some-system") 
    val tcpConsumer = system.actorOf(Props[TcpConsumer]) 
    } 
class TcpConsumer extends Consumer { 
    def endpointUri = "mina2:tcp://localhost:6200?textline=true" 
    def receive = { 
     case msg: CamelMessage => { 
      sender ! msg.bodyAs[String] 
      sender ! msg.bodyAs[String]  // This goes to dead letter 
      sender ! msg.bodyAs[String]  // This goes to dead letter 
     } 
     case msg: Failure => sender ! msg 
    } 
} 

ответ

0

Не зная слишком много о внутренностях AKKA интеграции/верблюд, позвольте мне попробовать и показать, что здесь происходит. Во-первых, как я уже упоминал в своем комментарии, sender в вашем акторе напрямую не ссылается на клиент TCP, который находится на другой стороне системы. Это более низкий уровень, чем это; это то, что ActorRef отправил ваш ConsumerCamelMessage в первую очередь. Так что это за актер? Позвольте мне попытаться объяснить, что я думаю, что происходит.

  1. При настройке протокола TCP на основе верблюд потребителя, на основе endpointUri будет кусок кода (от верблюда), который будет связываться с хостом и портом от endpointUri.
  2. Когда приходит новый запрос на подключение (на основе внешнего клиента, открывающего соединение с этим сокетом), какой-то актер, вероятно, развернут для обработки этого отдельного соединения. Таким образом, будут экземпляры актеров 1-n «обработчика соединения», соответствующие количеству открытых соединений.
  3. Когда сообщение приходит в исходное состояние, оно более чем вероятно проходит через этого агента обработчика соединения. Оттуда он либо отправляется вашему потребителю через ask (?), либо другой короткоживущий актер подтягивается для обработки этого индивидуального сообщения.
  4. В любом случае, следующая остановка - ваш потребитель, где функция receive получает удар с CamelMessage, представляющим полезную нагрузку из сообщения, отправленного с клиентом удаления. Когда это произойдет, актеры sender все равно отправили сообщение на шаге 3.
  5. Ваш потребитель отправит сообщение обратно в sender, а затем оттуда он будет перенаправлен обратно к обработчику соединения для этого соединения. Там он будет записывать обратно в сокет, в разговорном состоянии. Одно сообщение, одно сообщение.

Я думаю, ваша проблема в том, что вы нарушаете парадигму «один в одном». Когда вы получите свой CamelMessage, вы должны только ответить на это сообщение один раз, что будет протекать обратно к TCP-клиенту на другом конце сокета. Я не думаю, что структура ожидает другого ответа, и именно поэтому вы видите трибочки для двух других ответов.

Таким образом, возникает вопрос, какой у вас сценарий требует парадигмы «1 в 3» и ожидаемого «1 в, один», который, по-видимому, ожидает ожидать?

+0

Большое спасибо за ответ. Но даже после внесения этого изменения неправильное поведение остается неизменным. –

+0

Я предполагаю, что 'sender()' в данном случае является короткоживущим актером, используемым для 'Future'. Он может быть отреагирован только один раз, прежде чем он остановится (после завершения «Обещания», привязанного к «Будущему»). Вот почему вторая вторая всегда приводит к мертвым буквам. – cmbaxter

+0

Здесь отправитель() НЕ является клиентом, основанным на актерах. Это всего лишь клиент TCP. Вся идея заключается в создании серверного компонента, который по-прежнему поддерживает существующие клиенты и приложения. Так есть ли способ сделать то же самое? Спасибо –

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