运行 多个 NettyServer 播放 2.5 时连接被拒绝

Connection refused when running multiple NettyServer with play 2.5

我目前正在从 play 2.4 迁移到 2.5。

我正在尝试 运行 测试中的许多 NettyServer,但我只能访问最后创建的

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import org.scalatest.{FlatSpec, Matchers}
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.time.{Seconds, Span}
import play.api.libs.ws.ahc.AhcWSClient
import play.api.mvc.{Action, Results}
import play.core.server.{NettyServer, ServerConfig}
import play.api.routing.sird._

class NettyServerTest extends FlatSpec with Matchers with ScalaFutures {

  override implicit val patienceConfig = PatienceConfig(Span(5, Seconds))

  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()

  private val wsClient = AhcWSClient()

  it should "print 'Hello I am the secondServer' then 'Hello I am the firstServer'" in {

    val firstServer = createServer("firstServer")
    val secondServer = createServer("secondServer")
    try {
      println(wsClient.url(s"http://localhost:${secondServer.httpPort.get}/hello").get().futureValue.body)
      println(wsClient.url(s"http://localhost:${firstServer.httpPort.get}/hello").get().futureValue.body)
    } finally {
      firstServer.stop()
      secondServer.stop()
    }
  }

  def createServer(server: String): NettyServer = {
    NettyServer.fromRouter(ServerConfig(port = Some(0))) {
      case GET(p"/hello") => Action {
        Results.Ok(s"Hello I am the $server")
      }
    }
  }
}

当我 运行 测试时它只打印 'Hello I am the secondServer' 然后我得到错误:

The future returned an exception of type: java.net.ConnectException, with message: Connection refused: no further information: localhost/0:0:0:0:0:0:0:1:58096.
ScalaTestFailureLocation: NettyServerTest$$anonfun at (NettyServerTest.scala:28)
org.scalatest.exceptions.TestFailedException: The future returned an exception of type: java.net.ConnectException, with message: Connection refused: no further information: localhost/0:0:0:0:0:0:0:1:58096.
    at org.scalatest.concurrent.Futures$FutureConcept$class.tryTryAgain(Futures.scala:531)
    at org.scalatest.concurrent.Futures$FutureConcept$class.futureValue(Futures.scala:558)
    at org.scalatest.concurrent.ScalaFutures$$anon.futureValue(ScalaFutures.scala:74)
    at NettyServerTest$$anonfun.apply$mcV$sp(NettyServerTest.scala:28)
    at NettyServerTest$$anonfun.apply(NettyServerTest.scala:22)
...

我有以下依赖项:

"com.typesafe.play" %% "play-netty-server" % "2.5.4"
"com.typesafe.play" %% "play-ws" % "2.5.4"

此测试适用于 play 2.4

最后我通过覆盖 netty 服务器使用的 actorSystem 成功地使其工作:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.time.{Seconds, Span}
import org.scalatest.{FlatSpec, Matchers}
import play.api.BuiltInComponents
import play.api.libs.ws.ahc.AhcWSClient
import play.api.mvc.{Action, Results}
import play.api.routing.Router
import play.api.routing.sird._
import play.core.server.{NettyServer, NettyServerComponents, ServerConfig}

class NettyServerTest extends FlatSpec with Matchers with ScalaFutures {

  override implicit val patienceConfig = PatienceConfig(Span(5, Seconds))

  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()

  private val wsClient = AhcWSClient()

  it should "print 'Hello I am the secondServer' then 'Hello I am the firstServer'" in {

    val firstServer = createServer("firstServer")
    val secondServer = createServer("secondServer")
    try {
      wsClient.url(s"http://localhost:${firstServer.httpPort.get}/hello").get().futureValue.body shouldBe "Hello I am the firstServer"
      wsClient.url(s"http://localhost:${secondServer.httpPort.get}/hello").get().futureValue.body shouldBe "Hello I am the secondServer"
    } finally {
      firstServer.stop()
      secondServer.stop()
    }
  }

  def createServer(serverName: String): NettyServer = {
    new NettyServerComponents with BuiltInComponents {
      lazy val router = Router.from {
        case GET(p"/hello") => Action {
          Results.Ok(s"Hello I am the $serverName")
        }
      }
      override lazy val serverConfig = ServerConfig(port = Some(0))
      override lazy val actorSystem: ActorSystem = ActorSystem()
    }.server
  }
}