我想要做的基本上是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
是一个密封的特征,可能是有充分理由的......
答案 0 :(得分:2)
定义MessageFlowTransformer[Either[String, Array[Byte]], Either[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)
})
}
}
}