Scala 尝试连接到远程参与者时出现Akka BindException:地址已在使用中
我正在尝试使用Akka remote actors,试图通过网络建立一个简单的2人游戏。之前的一个问题给了我一个很好的起点,但现在我很难理解如何适应我的情况。ISTM表明原始用户从同一个客户端连接了两次(请参见下面的注释部分)。我要做的是从不同的客户端运行两次,但当我运行时,我会得到一个BindException,地址已经在使用中。我想这是因为每次我运行代码时,它都试图启动服务器?我需要一种情况,我可以启动和停止主演员独立的客户端连接和断开。(最小)Akka配置和异常在代码之后:Scala 尝试连接到远程参与者时出现Akka BindException:地址已在使用中,scala,akka,actor,Scala,Akka,Actor,我正在尝试使用Akka remote actors,试图通过网络建立一个简单的2人游戏。之前的一个问题给了我一个很好的起点,但现在我很难理解如何适应我的情况。ISTM表明原始用户从同一个客户端连接了两次(请参见下面的注释部分)。我要做的是从不同的客户端运行两次,但当我运行时,我会得到一个BindException,地址已经在使用中。我想这是因为每次我运行代码时,它都试图启动服务器?我需要一种情况,我可以启动和停止主演员独立的客户端连接和断开。(最小)Akka配置和异常在代码之后: import
import akka.actor._
//example from answer to https://stackoverflow.com/questions/15527193/keeping-references-to-two-actors
// by Patrick Nordwall
case object JoinMsg
case class Msg(s: String)
class Server extends Actor {
def receive = {
case JoinMsg =>
println("got player 1")
sender ! Msg("Waiting for player 2")
context.become(waitingForPlayer2(sender))
}
def waitingForPlayer2(client1: ActorRef): Actor.Receive = {
case JoinMsg =>
println("got player 2")
sender ! Msg("hi")
client1 ! Msg("hi")
context.become(ready(client1, sender))
}
def ready(client1: ActorRef, client2: ActorRef): Actor.Receive = {
case m: Msg if sender == client1 => client2 ! m
case m: Msg if sender == client2 => client1 ! m
}
}
/* I want to run this once for each "player" */
object Demo extends App {
val system = ActorSystem("Game")
val server = system.actorOf(Props[Server], "server")
system.actorOf(Props(new Actor {
server ! JoinMsg
def receive = {
case Msg(s) => println(s)
}
}))
/* Rather than connecting twice from the same node, I want to run this
program twice from different nodes
system.actorOf(Props(new Actor {
server ! JoinMsg
def receive = {
case Msg(s) => println(s)
}
}))*/
}
配置:
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
transport = "akka.remote.netty.NettyRemoteTransport"
netty {
hostname = "localhost"
port = 9000
}
}
}
例外情况:
Exception in thread "main" java.lang.ExceptionInInitializerError
at akkademo.main(akkademo.scala)
Caused by: org.jboss.netty.channel.ChannelException: Failed to bind to: localhost/127.0.0.1:9000
at org.jboss.netty.bootstrap.ServerBootstrap.bind(ServerBootstrap.java:298)
at akka.remote.netty.NettyRemoteServer.start(Server.scala:54)
at akka.remote.netty.NettyRemoteTransport.start(NettyRemoteSupport.scala:90)
at akka.remote.RemoteActorRefProvider.init(RemoteActorRefProvider.scala:94)
at akka.actor.ActorSystemImpl._start(ActorSystem.scala:588)
at akka.actor.ActorSystemImpl.start(ActorSystem.scala:595)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:111)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:93)
at akkademo$.<init>(akkademo.scala:4)
at akkademo$.<clinit>(akkademo.scala)
... 1 more
Caused by: java.net.BindException: Address already in use
线程“main”java.lang.ExceptionInInitializeError中的异常
在akkademo.main(akkademo.scala)
原因:org.jboss.netty.channel.ChannelException:未能绑定到:localhost/127.0.0.1:9000
位于org.jboss.netty.bootstrap.ServerBootstrap.bind(ServerBootstrap.java:298)
在akka.remote.netty.NettyRemoteServer.start(Server.scala:54)
在akka.remote.netty.nettyremoteransport.start(NettyRemoteSupport.scala:90)
位于akka.remote.RemoteActorRefProvider.init(RemoteActorRefProvider.scala:94)
在akka.actor.ActorSystemImpl.\u启动(ActorSystem.scala:588)
在akka.actor.ActorSystemImpl.start(ActorSystem.scala:595)
在akka.actor.ActorSystem$.apply上(ActorSystem.scala:111)
在akka.actor.ActorSystem$.apply(ActorSystem.scala:93)
akkademo$(akkademo.scala:4)
在akkademo$(akkademo.scala)
... 还有一个
原因:java.net.BindException:地址已在使用中
TIA。在同一台机器上运行多个实例时,需要为它们配置不同的端口。 在本例中,只有服务器需要一个已知端口(9000)。 对于客户端,可以使用0作为随机可用端口 为客户端定义另一个配置文件
client.conf
:
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
transport = "akka.remote.netty.NettyRemoteTransport"
netty {
hostname = "localhost"
port = 0
}
}
}
在具有此配置的客户端中启动ActorSystem
:
import com.typesafe.config.ConfigFactory
val system = ActorSystem("Game", ConfigFactory.load("client"))
在客户端中,您将使用以下内容查找服务器:
val server = system.actorFor("akka://Game@localhost:9000/user/server")
您需要单独指定客户端配置的端口,或者将服务器端配置的端口从2552更改为其他端口。2552是akka actor系统的默认端口,当您在客户端创建一个actor系统进行查找(在同一台机器上)时,如果没有明确指定端口2552,它也会尝试绑定到端口2552,因此会出现此错误。另一种更简单的方法是关闭所有终端窗口并打开新窗口。即使在停止所有节点后也面临相同的问题,但将在同一个终端中运行,而不是打开新的谢谢Patrick。
system
的声明给了我一个错误:required type com.typesafe.config.config。我正在使用Akka 2.0.5和scala 2.9.Great,这对我来说很好:-)如果有人想做同样的事情,我从中复制以使服务器能够启动和工作。现在似乎需要通过Akka.remote.netty.tcp.port
设置端口,而不是Akka.remote.netty.port
。