2013-04-18 5 views
2

У меня есть система Akka, работающая на Android-устройстве, которая разговаривает с системой Akka на сервере через Akka Remoting.Поддерживает ли Akka Remoting односторонние соединения?

Устройство Android может получить любой IP-адрес, IP-адрес может измениться при запуске приложения, а IP-адрес может быть недоступен с сервера. Таким образом, я настроил Akka на устройстве Android с akka.remote.netty.hostname = "0.0.0.0" и akka.remote.netty.port = 8000.

Система Android Akka получает ссылку на актера на сервере, отправляет ему сообщения, а Актер на сервере записывает отправителя() actorRef и продолжает отправлять сообщения обратно на него. Это работает, когда и сервер, и Android-устройство находятся на одном и том же wlan, и когда они разговаривают через GPRS через Интернет.

Теперь я более подробно рассмотрю потери связи и соединения. Сценарий, который я сосредоточил на этом:

  • Устройство и сервер Android находятся на wlan.
  • Устройство Android отправляет сообщение серверу.
  • Акция, удаленная на Android, производит RemoteClientStarted.
  • Akka удаленный сервер производит RemoteClientStarted и RemoteServerClientConnected.
  • Затем отключите wlan на Android, подождите несколько секунд и включите его снова. Никакие сообщения не отправляются на сервер между ними.
  • Akka Remoting на Android производит RemoteClientShutdown и RemoteClientError (ETIMEDOUT)
  • Akka Remoting на сервере ничего не говорит.
  • Android отправляет сообщение серверу.
  • Сервер производит RemoteServerClientConnected и получает сообщение.
  • сервер пытается отправить сообщение (назовем его на вопросы ниже) для Android, и производит: RemoteServerError, RemoteServerClientDisconnected, RemoteClientShutdown, RemoteServerClientClosed.
  • Android никогда не получает сообщение с сервера.
  • сервер пытается отправить еще одно сообщение, но Akkas RemoteClient говорит:
    • [PassiveRemoteClient @ Akka: //[email protected]: 8000] была отключена,
    • Запуск удаленного подключения клиента к [ Акко: //[email protected]: 8000 | /0.0.0.0]
    • RemoteClientError @ Akka: //[email protected]: 8000: Ошибка [...

Эта последняя ошибка, похоже, исходит из того, что Akka Remote хочет создать новый ActiveRemoteClient вместо повторного использования существующего PassiveRemoteClient. Я предполагаю, что это снова происходит от того, что сервер наблюдает за событием RemoteServerClientConnected, прежде чем он увидит ошибки/разъединения/shutdowns/clientcloseds.

Теперь вопросы:

  1. Как я могу сделать повторное использование последнего входящего соединения (PassiveRemoteClient) с Android устройства сервера при отправке сообщения А в этом случае?
  2. Как я могу дать указание серверу никогда не пытаться подключиться к клиенту?

Версии:

  • Android: 15 (4.0.3)
  • Akka: 2,1
  • Java: 1.6 64бит
  • Scala: 2.10.1
  • Нетти: 3,5 .8

ответ

7

Это может быть не реально это ответ, на который вы надеялись, но здесь он идет (я - ведущий специалист Akka).

Akka remoting предназначен для работы между системами, которые действуют как сверстники. Водителем разработки является создание поддержки кластера, которая появилась в версии 2.1 и которая будет официально поддерживаться и развиваться - начиная с версии 2.2. Это имеет несколько важных последствий:

  • ActorRefs должно быть место прозрачное, а это означает, что они не работают так же, независимо от того, где вы их используете, и, следовательно, каждый узел должен иметь возможность подключиться к узлу, когда определенные опорные точки к.
  • Связь между узлами Akka принципиально симметрична, даже если ваше использование этого не может быть.
  • Передача ActorRef в качестве средства ведения разговора означает, что объект, на который указывает ссылка, должен оставаться доступным или сообщение не будет выполнено; и пребывание в распоряжении означает «в том же месте, на которое указывает ссылка».

Что это означает для вашего сценария, так это то, что вам будет лучше отключить свои актерские системы, не используя простой удаленный доступ, вместо этого используя что-то еще, что поддерживает ассоциации, которые вы страдаете от коротких событий. Например, вы можете открыть сервер как службу REST, или вы можете просто использовать пустой TCP (или даже UDP) с использованием уровня Akka IO. В роли актера, обрабатывающего конечную точку на стороне сервера, вы можете узнать, может ли тот же самый клиент разговаривать с вами из разных мест сети, отправлять сообщения ответа буфера, маскировать внешний субъект за локальным прокси-актером и т. Д. С помощью этой схемы вы можете даже построить надежная передача сообщений по вашим ненадежным каналам (с использованием ACKing), и красота заключается в том, что на сервере (возможно, в кластере) все сообщение работает только потому, что проблематичная часть того, как разговаривать с клиентом, инкапсулирована в одно место.

Краткая история: ваш прецедент не является одним из тех, который поддерживается обычным удалением Akka из коробки.

+0

Спасибо за подробный ответ и особенно предложения о том, как заставить его работать. Быстрое отслеживание: 'RemoteTransport', похоже, является базой для реализации собственных удаленных под Akka. Это недокументировано, поэтому я должен спросить: это рекомендуемый способ? Будет ли механизм радикально изменяться в будущих версиях Akka? – eirirlar

+0

RemoteTransport изменится на 2.2, и хотя вполне возможно, что специальные приложения создают свои собственные, мы не ожидаем, что это произойдет часто. Есть много предположений, связанных с обменом акторами, которые могут не соответствовать вашим потребностям. –

+0

Хорошо, предположим, я буду держаться подальше от «RemoteTransport». Для любопытных: Я закончил тестирование akka-zeromq. Он построен против zeromq-2.1, что было неприемлемо для меня. Поэтому я тестировал jeromq, который должен быть чистым java-портом zeromq3. К сожалению, это не сработало как замена замены scala-zeromq, которая поставляется с akka-zeromq, но я разблокировал модуль akka-zeromq и заменил зависимость от scala-zeromq-binding с jeromq вместо этого. Работает как очарование , но тестирование на Android по-прежнему остается. – eirirlar