在 Play 中使用

Module Info

需要在项目中添加如下依赖:

sbt
libraryDependencies += "com.akka-fusion.fusion" %% "discoveryx-client-play-ws" % "0.1.0"
Gradle
dependencies {
  compile group: 'com.akka-fusion.fusion', name: 'discoveryx-client-play-ws_2.13', version: '0.1.0'
}
Maven
<dependency>
  <groupId>com.akka-fusion.fusion</groupId>
  <artifactId>discoveryx-client-play-ws_2.13</artifactId>
  <version>0.1.0</version>
</dependency>
服务发现

discoveryx-client-play-ws基于discoveryx-client开发,有关Scala SDK与服务发现配置内容请参阅 Scala SDK在 Akka 中使用

SDK

Fusion DiscoveryX 提供了 DiscoveryXWSClient 工具类来创建或包装一个StandaloneWSClientWSClientDiscoveryXStandaloneWSClient实现了StandaloneWSClient接口并重写了url函数,使其可以解析请求URL里面的hostname部分并将其转换成实际访问的ip:port地址。

StandaloneWSClient

Play已将WSClient拆分独立出来,我们可以单独使用它。

Scala
def standaloneWSClient()(implicit system: ActorSystem[_]): DiscoveryXStandaloneWSClient =
  standaloneWSClient(StandaloneAhcWSClient())

def standaloneWSClient(client: StandaloneWSClient)(implicit system: ActorSystem[_]): DiscoveryXStandaloneWSClient =
  new DiscoveryXStandaloneWSClient(client)
Java
public static DiscoveryXStandaloneWSClient standaloneWSClient(StandaloneWSClient client, ActorSystem<?> system) {
    return new DiscoveryXStandaloneWSClient(client, system);
}

public static DiscoveryXStandaloneWSClient standaloneWSClient(ActorSystem<?> system) {
    return standaloneWSClient(StandaloneAhcWSClient.create(
            AhcWSClientConfigFactory.forConfig(system.settings().config(), system.dynamicAccess().classLoader()),
            SystemMaterializer.get(system).materializer()), system);
}

使用

val client = DiscoveryXWSClient.standaloneWSClient()
val url = "http://fusion-schedulerx/cluster/health"
val req = client.url(url)
req.url should not be url
req.url should not contain "fusion-schedulerx"

WSClient

使用 Playframework 附带的 WSClient 时,调用 StandaloneWSClientwsClient 函数新建或包装一个 WSClient

Scala
def wsClient()(implicit system: ActorSystem[_]): DiscoveryXPlayWSClient = wsClient(AhcWSClient())

def wsClient(client: WSClient)(implicit system: ActorSystem[_]): DiscoveryXPlayWSClient =
  new DiscoveryXPlayWSClient(client)(system)

def wsClient(asyncHttpClient: AsyncHttpClient)(implicit system: ActorSystem[_]): DiscoveryXPlayWSClient =
  wsClient(new AhcWSClient(new StandaloneAhcWSClient(asyncHttpClient)))
Java
public static DiscoveryXPlayWSClient wsClient(WSClient client, ActorSystem<?> system) {
    return new DiscoveryXPlayWSClient(client, system);
}

public static DiscoveryXPlayWSClient wsClient(AsyncHttpClient asyncHttpClient, ActorSystem<?> system) {
    return wsClient(new AhcWSClient(asyncHttpClient, SystemMaterializer.get(system).materializer()), system);
}

public static DiscoveryXPlayWSClient wsClient(ActorSystem<?> system) {
    return wsClient(
            AhcWSClient.create(
                    AhcWSClientConfigFactory.forConfig(system.settings().config(), system.dynamicAccess().classLoader()),
                    null,
                    SystemMaterializer.get(system).materializer()),
            system);
}

使用

import javax.inject.Inject

import fusion.discoveryx.client.play.scaladsl.DiscoveryXPlayWSClient
import fusion.discoveryx.client.play.scaladsl.DiscoveryXPlay
import scala.concurrent.Future
import scala.concurrent.duration._
import play.api.mvc._
import play.api.libs.ws._
import play.api.http.HttpEntity
import akka.actor.ActorSystem
import akka.stream.scaladsl._
import akka.util.ByteString

import scala.concurrent.ExecutionContext

// 直接注入
class MainForImmediately @Inject() (
  ws: DiscoveryXPlayWSClient,
  val controllerComponents: ControllerComponents) extends BaseController {}

// 通过 @Named 注入
class MainForNamed @Inject() (
  @Named("discoveryx") ws: WSClient, 
  val controllerComponents: ControllerComponents) extends BaseController {}

// 通过附加注解
class MainForNamed @Inject() (
  @DiscoveryXPlay ws: WSClient, 
  val controllerComponents: ControllerComponents) extends BaseController {}

之后就可以在代码中通过 ws 来访问HTTP了:

val request: WSRequest = ws.url(url)
在此文档中发现错误?该页面的源代码可以在 这里 找到。欢迎随时编辑并提交Pull Request。