Playframework Akka WebSocket.accept How to use derived classes and MessageFlowTransformer

Viewed 503

Using Playframework 2.5, Akka and Websockets I would like to be able to declare a websocket that accepts different incoming and outcoming classes, those classes would have a base class (one base class for incoming and another one for outcoming messages). Here's where I am :

object IncomingMessage {
    val subscribeMessage = "subscribe"
    val unsubscribeMessage = "unsubscribe"
}

abstract class IncomingMessage(action: String)

case class SubscribeMessage(repository: String, interval: Int, action: String = IncomingMessage.subscribeMessage) extends IncomingMessage(action)
case class UnsubscribeMessage(repository: String, action: String = IncomingMessage.unsubscribeMessage) extends IncomingMessage(action)

object SubscribeMessage {
    implicit val SubscribeMessageWrites: Reads[SubscribeMessage] = (
        (JsPath \ "repository").read[String] and
        (JsPath \ "interval").read[Int](min(1)) and
        (JsPath \ "action").read[String]
    )(SubscribeMessage.apply _)
}

object UnsubscribeMessage {
    implicit val UnsubscribeMessageWrites: Reads[UnsubscribeMessage] = (
        (JsPath \ "repository").read[String] and
        (JsPath \ "action").read[String]
    )(UnsubscribeMessage.apply _)
}

The outcoming messages are based on the same principal so I will not show them.

Reading the Play documentation I would implement something like this

import play.api.libs.json._
import play.api.mvc.WebSocket.FrameFormatter
implicit val incomingFormat = Json.format[IncomingMessage]
implicit val outcomingFormat = Json.format[OutcomingMessage]

implicit val messageFlowTransformer = MessageFlowTransformer.jsonMessageFlowTransformer[IncomingMessage, OutcomingMessage]

...

def socket = WebSocket.acceptOrResult[IncomingMessage, OutcomingMessage] { ... }

I would like to use formatters and the MessageFlowTransformer to be able to send messages without transforming them to json explicitly, so I don't want to write :

out ! Json.toJson(outcomingMessage)

But I would like to write

out ! outcomingMessage

But I get back an error during compile time for the implicit val incomingFormat AND the implicit val outcomingFormat

No unapply or unapplySeq function found

How can I solve this issue ? Is it possible to use derived classes as websocket messages using actors ?

0 Answers
Related