【发布时间】:2012-09-22 09:17:24
【问题描述】:
我正在尝试设置一个简单的服务器/客户端 akka(使用 Akka 2.0.3)应用程序,但无法连接。预先这里是基本代码:
import com.typesafe.config.ConfigFactory
import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.Props
class Server extends Actor {
def receive = {
case s: String => println("Got " + s)
}
}
val serverSystem = ActorSystem("server", ConfigFactory.load(ConfigFactory.parseString("""
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
remote {
transport = "akka.remote.netty.NettyRemoteTransport"
netty {
hostname = "localhost"
port = 5678
}
}
}
""")))
val server = serverSystem.actorOf(Props[Server], name = "server")
Thread.sleep(500)
println("started")
Thread.sleep(500)
val clientSystem = ActorSystem("client", ConfigFactory.load(ConfigFactory.parseString("""
akka {
actor {
provider = "akka.remote.RemoteActorRefProvider"
}
}
""")))
val remoteServer = clientSystem.actorFor("akka://server@XXX:5678/user/server")
remoteServer ! "HEY"
Thread.sleep(3000)
clientSystem.shutdown
serverSystem.shutdown
我知道配置应该放在外部文件中。
如果您将 XXX 替换为 localhost 它可以工作:
started
Got HEY
但是,如果我将外部(已解析)IP(家庭路由器后面的 PC)用于XXX,HEY 消息永远不会到达。我认为这是由于某些防火墙问题并在我的路由器上转发了相关的 TCP 和 UDP 端口,并在我的 Windows 防火墙上打开/允许它们。所以在那之后,下面的代码起作用了(XXX也被我的外部IP替换了)。一个启动的ServerTest 可以通过一个ClientTest 连接:
import java.net.ServerSocket
object ServerTest extends App {
println("START server")
val ss = new ServerSocket(5678)
val s = ss.accept()
println(s)
println("END")
}
import java.net.Socket
object ClientTest extends App {
println("START client")
val s = new Socket("XXX", 5678)
println(s)
println("END")
}
所以这不是端口/防火墙问题,不是吗?!那么问题出在哪里???
【问题讨论】:
-
Akka Remoting 不处理防火墙或 NAT:akka.io/faq
-
@Viktor 虽然它回答了我的问题,但我仍然想知道为什么套接字版本有能力而akka 没有。
-
@Viktor 您介意发表您的评论作为答案,以便我接受吗?!
-
顺便说一句,您需要在配置中将外部可访问的主机名或 IP 作为“主机名”。 “localhost”不是外部可访问的地址。