我正在尝试使用 Akka Http Client 向 REST Web 服务发出 GET 请求。
在进行 GET 之前,我无法弄清楚如何在请求上设置 cookie。
我在网上搜索,我找到了在服务器端读取 cookie 的方法。但我找不到任何向我展示如何在客户端请求上设置 cookie 的内容。
根据我自己的研究,我尝试了以下方法在 http 请求上设置 cookie
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.{Sink, Source}
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.headers.HttpCookie
import akka.stream.ActorMaterializer
import spray.json._
import scala.util.{Failure, Success}
case class Post(postId: Int, id: Int, name: String, email: String, body: String)
trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
implicit val postFormat = jsonFormat5(Post.apply)
}
object AkkaHttpClient extends JsonSupport{
def main(args: Array[String]) : Unit = …Run Code Online (Sandbox Code Playgroud) 我有简化的代码如下所示:
path("path") {
post {
val routeFuture: Future[StandardRoute] = Future {
//some app logic
utilFunctionRoute()
}
??? // complete the request
}
}
Run Code Online (Sandbox Code Playgroud)
有一次,我有 Future[StandardRoute] 包含我的结果,但我不知道如何在不阻塞 Future 的情况下完成此请求。
我不知道如何cachedHostConnectionPool使用 scala 在 akka-http 中创建发送https请求。queueRequest(HttpRequest(uri = "https://example.com")向 http 发送请求,cachedHostConnectionPool[Promise[HttpResponse]]("https://example.com")抛出一个:非预期字符的错误。
import scala.util.{ Failure, Success }
import scala.concurrent.{ Future, Promise }
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl._
import akka.stream.{ OverflowStrategy, QueueOfferResult }
implicit val system = ActorSystem()
import system.dispatcher // to get an implicit ExecutionContext into scope
implicit val materializer = ActorMaterializer()
val QueueSize = 10
// This idea came initially from this blog post:
// http://kazuhiro.github.io/scala/akka/akka-http/akka-streams/2016/01/31/connection-pooling-with-akka-http-and-source-queue.html
val …Run Code Online (Sandbox Code Playgroud) 我将 Scala 与 Akka HTTP 一起使用。
我有一个基于 Akka HTTP 的服务器后端应用程序。传入的 WebSocket 消息通过以下方式处理handleWebSocketMessages:
/**
* Route for WebSocket request
*/
private val webSocketRoute: Route = pathSuffix(Constants.WSPROXY_WEBSOCKET_PATH_SUFFIX) {
LOGGER.debug("() Web socket route")
handleWebSocketMessages(wsRouteImpl)
}
/**
* This method calls all registered handlers.
*
* @return flow for handleWebSocketMessages method
*/
private def wsRouteImpl: Flow[Message, Message, Any] = {
LOGGER.debug("() wsRouteHandling")
numOfClients += 1
LOGGER.info(s"Client has connected, current number of clients: $numOfClients")
var flow = Flow[Message].mapConcat {
// Call specific handlers …Run Code Online (Sandbox Code Playgroud) 我有以下采用路径参数的代码;
def candlesRange: Route = (path("candles" / Segment / Segment / IntNumber / LongNumber / LongNumber) & get) {
(a1, a2, tf, t1, t2) => complete(apiController.apiGetCandlesRange(a1, a2, tf, t1, t2))
}
Run Code Online (Sandbox Code Playgroud)
但我想将一些参数更改为查询参数。所以 URL 将遵循这样的格式;
/candles/Asset1/Asset2/timeStart=1507198441000&timeEnd=1512382501000&interval=60m
Run Code Online (Sandbox Code Playgroud)
并将它们传递给相同的方法(甚至可能从分钟中删除“m”,因为方法上的参数是一个整数)
如何在 Scala Akka Http 中更改此路由以执行此操作。我能找到的唯一示例使用 Path params
最后一个路径元素是可选的,所以我创建了这个匹配器
pathPrefix("the-endpoint" / Segment / Segment.?) { (left[String], right: Option[String]) => ... }
Run Code Online (Sandbox Code Playgroud)
问题是只有在添加尾随的“/”斜杠字符时才会调用此路径:
即不要添加最后的路径部分:
curl localhost:12345/the-endpoint/firstsegment
The requested resource could not be found
Run Code Online (Sandbox Code Playgroud)
但
curl localhost:12345/the-endpoint/firstsegment/
... all good , gets to the path as expected ...
Run Code Online (Sandbox Code Playgroud) 我尝试使用 Akka HTTP 向本地主机发送 get 请求,但出现以下异常:
EntityStreamSizeException: actual entity size (Some(10166731700)) exceeded content length limit (8388608 bytes)! You can configure this by setting akka.http.[server|client].parsing.max-content-length or calling HttpEntity.withSizeLimit before materializing the dataBytes stream.)
Run Code Online (Sandbox Code Playgroud)
基本上,我尝试请求的本地主机上的文件非常大。
我尝试使用 来解决它withoutSizeLimit,但它不起作用:
val request = Get("http://localhost:8080/oa-ok.ntriples")
val limitedRequest = request.withEntity(request.entity.withoutSizeLimit())
val responseFuture = Http().singleRequest(limitedRequest)
Run Code Online (Sandbox Code Playgroud)
我也尝试使用withSizeLimit,但没有帮助。有任何想法吗?
docker pull kovacshuni/riptube:1.0.0-SNAPSHOT
docker run -it -P --name="riptube" kovacshuni/riptube:1.0.0-SNAPSHOT
bin/riptube &
curl -X POST -d "Hi there" localhost:8082/notify
INFO 15:55:06 c.h.r.NotificationReceiver$ - Hi there
Run Code Online (Sandbox Code Playgroud)
所以这很有效.但是从外面,来自docker守护进程的主机,它没有.尽管有EXPOSE命令和-P参数.
docker port riptube 8082
0.0.0.0:32785
curl -X POST -d "Hi there" localhost:32785/notify
curl: (52) Empty reply from server
Run Code Online (Sandbox Code Playgroud)
为什么?:( :(
源代码在这里.Dockerfile也是如此,但是粘贴在下面:
FROM frolvlad/alpine-oraclejdk8
RUN apk add --update bash py-pip ca-certificates curl
RUN rm -rf /var/cache/apk/*
RUN pip install youtube-dl
WORKDIR /opt/riptube
ADD target/pack/ /opt/riptube
EXPOSE 8082
ENTRYPOINT /bin/bash
CMD
Run Code Online (Sandbox Code Playgroud) 我有一个fork连接调度程序配置为仅使用akka http的客户端(通过主机连接池)的服务:
my-dispatcher {
type = Dispatcher
executor = "fork-join-executor"
fork-join-executor {
parallelism-min = 256
parallelism-factor = 128.0
parallelism-max = 2048
}
}
Run Code Online (Sandbox Code Playgroud)
服务逻辑唯一要做的就是从外部源请求,使用jawn解组它,然后将jawn ast转换为case类:
def get(uri: Uri)[T]: Future[T] = {
for {
response <- request(uri)
json <- Unmarshal(response.entity).to[Try[JValue]]
} yield json.transformTo[T]
}
Run Code Online (Sandbox Code Playgroud)
我想知道为这种工作负载使用固定线程池是否更有效.这项服务大约需要150 req/s,我想将CPU使用率保持在1 CPU以下(目前它的徘徊在1.25-1.5左右).
我刚开始使用Akka和Scala,并尝试使用Akka Streams连接到WebSocket。我创建了SocketActor下面的示例,并尝试从main方法实例化。
这是我的SocketActor:
package com.lightbend.akka.sample
import akka.actor.{Actor, Props}
import akka.Done
import akka.http.scaladsl.Http
import akka.stream.scaladsl._
import akka.http.scaladsl.model.ws._
import scala.concurrent.Future
object SocketActor {
def props(coinApiIdentifier: String): Props = Props(new SocketActor(coinApiIdentifier))
case object Start
case object Stop
}
class SocketActor(val ticker: String) extends Actor {
import SocketActor._
// Future[Done] is the materialized value of Sink.foreach,
// emitted when the stream completes
private val incoming: Sink[Message, Future[Done]] =
Sink.foreach[Message] {
case message: TextMessage.Strict =>
println(message.text)
}
// send this as …Run Code Online (Sandbox Code Playgroud)