我想要做的基本上是1:1这个: Scala Play Websocket – use one out actor to send both: Array[Byte] and String messages
可悲的是,自2.4以来,API发生了很大的变化(我现在在2.6.0-M4上).
我尝试了什么(由于显而易见的原因不编译):
WebSocket.accept[WSMessage, WSMessage]
{
request =>
ActorFlow.actorRef
{
out => WebSocketActor.props(out)
}
}
sealed trait WSMessage
case class StringMessage(s: String) extends WSMessage
case class BinaryMessage(a: Array[Byte]) extends WSMessage
case class JsonMessage(js: JsValue) extends WSMessage
object MyMessageFlowTransformer
{
implicit val WSMessageFlowTransformer: MessageFlowTransformer[WSMessage, WSMessage] =
{
new MessageFlowTransformer[WSMessage, WSMessage]
{
def transform(flow: Flow[WSMessage, WSMessage, _]) =
{
AkkaStreams.bypassWith[Message, WSMessage, Message](Flow[Message] collect
{
case StringMessage(s) => Left(s)
case BinaryMessage(b) => Left(b)
case JsonMessage(j) => Left(j)
case _ => Right(CloseMessage(Some(CloseCodes.Unacceptable)))
})(flow map WSMessage.apply)
}
}
}
}
我有点迷茫. play.api.http.websocket.Message是一个密封的特性,可能有充分的理由……
最佳答案 定义MessageFlowTransformer [[String,Array [Byte]],[String,Array [Byte]]]:
type WSMessage = Either[String, Array[Byte]]
implicit val mixedMessageFlowTransformer: MessageFlowTransformer[WSMessage, WSMessage] = {
new MessageFlowTransformer[WSMessage, WSMessage] {
def transform(flow: Flow[WSMessage, WSMessage, _]) = {
AkkaStreams.bypassWith[Message, WSMessage, Message](Flow[Message].collect {
case BinaryMessage(data) => Left(Right(data.toArray))
case TextMessage(text) => Left(Left(text))
})(flow map {
case Right(data) => BinaryMessage.apply(ByteString.apply(data))
case Left(text) => TextMessage.apply(text)
})
}
}
}