2016-04-27 75 views
2

我是新的阿卡,我使用Akka 2.3.3版本创建演员。我将创建远程角色并尝试访问客户端。每当我要运行测试用例,下面的异常会抛出:Akka演员:远程演员异常“期货超时后”

[INFO] [04/27/2016 07:51:23.727] [Localsystem-akka.actor.default-dispatcher-3] [akka://Localsystem/deadLetters] Message [com.harmeetsingh13.chapter2.messages.SetRequest] from Actor[akka://Localsystem/temp/$a] to Actor[akka://Localsystem/deadLetters] 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'. 
[INFO] [04/27/2016 07:51:23.745] [Localsystem-akka.actor.default-dispatcher-3] [akka://Localsystem/deadLetters] Message [com.harmeetsingh13.chapter2.messages.GetRequest] from Actor[akka://Localsystem/temp/$b] to Actor[akka://Localsystem/deadLetters] was not delivered. [2] 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'. 

Futures timed out after [10 seconds] 
java.util.concurrent.TimeoutException: Futures timed out after [10 seconds] 
at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:219) 
at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:223) 
at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:190) 
at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53) 
at scala.concurrent.Await$.result(package.scala:190) 
at com.harmeetsingh13.chapter2.SClientIntegrationSpec$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(SClientIntegrationSpec.scala:18) 
at com.harmeetsingh13.chapter2.SClientIntegrationSpec$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(SClientIntegrationSpec.scala:15) 
at com.harmeetsingh13.chapter2.SClientIntegrationSpec$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(SClientIntegrationSpec.scala:15) 
at org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22) 
at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85) 
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104) 
at org.scalatest.Transformer.apply(Transformer.scala:22) 
at org.scalatest.Transformer.apply(Transformer.scala:20) 
at org.scalatest.FunSpecLike$$anon$1.apply(FunSpecLike.scala:422) 
at org.scalatest.Suite$class.withFixture(Suite.scala:1122) 
at com.harmeetsingh13.chapter2.SClientIntegrationSpec.withFixture(SClientIntegrationSpec.scala:11) 
at org.scalatest.FunSpecLike$class.invokeWithFixture$1(FunSpecLike.scala:419) 
at org.scalatest.FunSpecLike$$anonfun$runTest$1.apply(FunSpecLike.scala:431) 
at org.scalatest.FunSpecLike$$anonfun$runTest$1.apply(FunSpecLike.scala:431) 
at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306) 
at org.scalatest.FunSpecLike$class.runTest(FunSpecLike.scala:431) 
at com.harmeetsingh13.chapter2.SClientIntegrationSpec.runTest(SClientIntegrationSpec.scala:11) 
at org.scalatest.FunSpecLike$$anonfun$runTests$1.apply(FunSpecLike.scala:464) 
at org.scalatest.FunSpecLike$$anonfun$runTests$1.apply(FunSpecLike.scala:464) 
at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:413) 
at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:401) 
............ 

下面我的服务器代码: Main.scala

object Main extends App{ 


private val configFile = getClass.getClassLoader.getResource("application.conf").getFile; 
private val config = ConfigFactory.parseFile(new File(configFile)) 

val system = ActorSystem("SimpleClientServer", config) 
system.actorOf(Props[AkkadmeyDB], name = "akkademy-db") 
} 

application.conf:

akka{ 
actor{ 
    provider = "akka.remote.RemoteActorRefProvider" 
} 
remote{ 
enabled-transports = ["akka.remote.netty.tcp"] 
    netty.tcp { 
    hostname = "127.0.0.1" 
    port = 2552 
    } 
    log-sent-messages = on 
    log-received-messages = on 
} 
} 

AkkadmeyDB.scala演员等级:

class AkkadmeyDB extends Actor{ 

val map = new HashMap[String, Object] 
val log = Logging(context.system, this) 

override def receive: Receive = { 
    case SetRequest(key, value) => 
    log.info("received SetRequest - key: {} value: {}", key, value) 
    map.put(key, value) 
    sender() ! Status.Success 
    case GetRequest(key) => 
    log.info("received GetRequest - key: {}", key) 
    val response = map.get(key) 
    response match{ 
    case Some(x) => sender() ! x 
    case None => Status.Failure(new KeyNotFoundException(key)) 
    } 
    case o => Status.Failure(new ClassNotFoundException()) 
    } 
} 
0123如下

客户端代码: SClient.scala

class SClient(remoteIp: String) { 

    private implicit val timeout = Timeout(10 seconds) 
    private implicit val system = ActorSystem("Localsystem") 
    private val remoteAddress = s"akka.tcp://[email protected]$remoteIp/user/akkademy-db"; 
    private val remoteDb = system.actorSelection(remoteAddress) 

    def set(key: String, value: Object) = { 
    remoteDb ? SetRequest(key, value) 
    } 

    def get(key: String) = { 
    remoteDb ? GetRequest(key) 
    } 
} 

SClientIntegrationSpec.scala测试用例:

class SClientIntegrationSpec extends FunSpecLike with Matchers { 

    val client = new SClient("127.0.0.1:2552") 
    describe("akkadment-db-client"){ 
    it("should set a value"){ 
     client.set("jame", new Integer(1313)) 
     val futureResult = client.get("james") 
     val result = Await.result(futureResult, 10 seconds) 
     result should equal (1313) 
    } 
    } 
} 

,当我看到我的远程应用程序的日志,这似乎是,请求命中没有按” t去服务器。我的示例代码运行时出现了什么问题?

+1

嘿它的贾森·古德温 - 我看到了你的鸣叫。你可以把你的代码推到github上吗?我已经在发布之前检查了所有发布在我的github上的示例工作。我会帮你的。 – JasonG

+0

嗨@JasonG谢谢你的回复。我没有使用从你的仓库下载的代码,我正在根据你的章节创建我自己的代码。将代码分成两个存储库服务器和客户端。在Server Repo中,转到第2章包https://github.com/harmeetsingh0013/Akka-practice-using-scala和客户端repo https://github.com/harmeetsingh0013/Akka-practice-using-scala-client。正如我上面提到的,服务器代码运行成功,但是当我试图运行客户端测试用例时,那么我得到了和上面提到的异常。 –

+0

谢谢,我会在稍后检查并回复给您。 – JasonG

回答

3

为了解决上述问题,我们需要遵循两个步骤是低于metnion:

  1. 当我创建一个服务器代码,我不包括我的服务器应用程序application.conf,这就是为什么,客户端应用程序不能够与服务器连接。该代码使用built.sbt是如下:

    mappings in (Compile, packageBin) ~= { _.filterNot { case (_, name) => 
    Seq("application.conf").contains(name) 
    }} 
    

上面的代码注释后,客户端看到的服务器成功。

  • Learning Scala第2章jasongoodwin解释客户机和服务器系统演员的代码。但是在书中有一些勘误表和缺少application.conf配置的客户端。因为当我们在同一台PC上运行这两个代码时,我们面临已经是端口绑定异常,因为默认情况下,参与者使用端口2552进行访问,并且我们已经为我们的服务器应用程序定义了此端口。所以,application.conf还需要客户端如下:

    akka { 
        actor { 
        provider = "akka.remote.RemoteActorRefProvider" 
        } 
        remote { 
        enabled-transports = ["akka.remote.netty.tcp"] 
        netty.tcp { 
         hostname = "127.0.0.1" 
         port = 0 
        } 
        log-sent-messages = on 
        log-received-messages = on 
        } 
    } 
    
  • 这里Port 0意味着任何空闲的端口。

    之后,上面的代码运行成功。

    +0

    我强烈建议您按照github中提供的代码示例进行操作,而不是自己写。它会节省你很多时间。我对java代码示例也是这样做的,到目前为止它一直是顺利的。是的,你是对的,书中没有提到客户端代码的application.conf。需要注意的是,客户端和服务器都是相同的,并且需要启用远程配置。 – Neeraj

    +0

    非常感谢。 –

    1

    在客户端项目中还有一个application.conf文件,这在本书中没有提到。 确保您创建的资源文件夹下的该文件,内容如下:

    akka { 
        actor { 
        provider = "akka.remote.RemoteActorRefProvider" 
        } 
    } 
    

    official github repo

    +0

    是的,这是有效的。请注意,如果您正在运行Java示例,那么您可能还需要配置端口“remote.netty.tcp.port = 0”,如GitHub中的Java示例所示,否则第一次运行测试时,如果将运行良好,但如果您重新运行而没有弹起Activator,它将在随后的尝试中失败。这个设置不在Scala例子中,起初对我来说有点困惑。不知道这是否是疏忽,还是Scala没有必要。 https://github.com/jasongoodwin/learning-akka/blob/master/ch2/akkademy-db-client-java/src/main/resources/application.conf – rscarter