我正在尝试实现一个基本的广播路由器,其中路由在远程机器上.
代码如下:
localApp.conf
akka { log-dead-letters = 10 log-dead-letters-during-shutdown = off actor { provider = "akka.remote.RemoteActorRefProvider" serialize-messages = on serializers { java = "akka.serialization.JavaSerializer" } serialization-bindings { "java.lang.String" = java "test.akkaLocal.LocalWrapper" = java } deployment { /LocalMaster/broadcastRouter { router = "broadcast" nr-of-instances = 1 target { nodes = ["akka.tcp://RemoteApp@127.0.0.1:10175"] } } } } remote { enabled-transports = ["akka.remote.netty.tcp"] netty { tcp { hostname = "127.0.0.1" port = 10174 } } } }
LocalApp.java
public class LocalApp { public static void main(String[] args) { LocalApp app = new LocalApp(); app.executeLocal(); } private void executeLocal() { ActorSystem system = ActorSystem.create("LocalApp", ConfigFactory.load("localApp")); final ActorRef master = system.actorOf(Props.create(LocalMaster.class), "LocalMaster"); master.tell(new LocalWrapper.Execute(), ActorRef.noSender()); } public static class LocalMaster extends UntypedActor { @Override public void onReceive(Object message) throws Exception { if (message instanceof LocalWrapper.Execute) { ActorSelection remoteActor = getContext().actorSelection("akka.tcp://RemoteApp@127.0.0.1:10175/user/RemoteMaster"); ActorRef remoteRouter = getContext().actorOf( Props.create(RemoteActor.class).withRouter(new FromConfig()), "broadcastRouter"); String msg = "Hello"; // remoteActor.tell(msg, getSelf()); remoteRouter.tell(msg, getSelf()); } else if (message instanceof String) { String response = (String) message; System.out.println(response); } } } public static class RemoteActor extends UntypedActor { @Override public void onReceive(Object message) throws Exception { if (message instanceof String) { String msg = (String) message; System.out.println(msg); String resp = "World"; getSender().tell(resp, getSelf()); } } } }
在remoteApp.conf中,端口为10175
RemoteApp.java
public class RemoteApp { public static void main(String[] args) { RemoteApp app = new RemoteApp(); app.executeRemote(); } private void executeRemote() { ActorSystem system = ActorSystem.create("RemoteApp", ConfigFactory.load("remoteApp")); system.actorOf(Props.create(RemoteMaster.class), "RemoteMaster"); } public static class RemoteMaster extends UntypedActor { @Override public void onReceive(Object message) throws Exception { if (message instanceof String) { String msg = (String) message; System.out.println(msg); String response = "World"; getSender().tell(response, getSelf()); } } } }
现在我无法理解远程路由的概念.它是在远程计算机上部署本地actor,然后向它们发送消息,还是连接到远程计算机上的远程actor,然后向它们发送消息?
使用我的代码,我能够将简单的消息发送到远程机器(使用actor选择),LocalApp中的remoteActor.tell(msg,getSelf())(注释代码)发送和接收消息,并且不会给出任何错误.
但是当我使用本地Actor创建路由器时,我得到了死信错误.
[INFO] [02/04/2014 16:34:58.408] [RemoteApp-akka.actor.default-dispatcher-4] [akka://RemoteApp/system/endpointManager/reliableEndpointWriter-akka.tcp%3A%2F%2FLocalApp%40127.0.0.1%3A10174-0/endpointWriter/endpointReader-akka.tcp%3A%2F%2FLocalApp%40127.0.0.1%3A10174-0] Message [akka.remote.transport.AssociationHandle$InboundPayload] from Actor[akka://RemoteApp/deadLetters] to Actor[akka://RemoteApp/system/endpointManager/reliableEndpointWriter-akka.tcp%3A%2F%2FLocalApp%40127.0.0.1%3A10174-0/endpointWriter/endpointReader-akka.tcp%3A%2F%2FLocalApp%40127.0.0.1%3A10174-0#-288427524] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
有人能告诉我我做错了什么吗?
--------- ----------更新
我发现了问题.远程和本地课程在不同的项目中.在本地和远程项目之间的基本通信期间,String是传输的对象的类型,它是成功的原因.有没有办法在两个不同的项目之间传输自定义类的对象?我尝试实现Serializable并将其添加到conf文件中,但它没有什么区别
默认情况下,akka将使用java序列化来定制消息类.如果类定义在系统两侧(发送方和接收方)可用(即在类路径中),那么您应该能够将其用于远程通信.我的建议是使用一个jar文件来表示系统两侧的类路径中可用的消息类.
Akka还允许您为不同的消息类类型使用不同的序列化程序,因此您不会遇到Java序列化,但我建议在尝试使用其他序列化程序之前先让它以这种方式工作,如果您有这种倾向.