스케이프 2.5의 플레이 프레임 워크 2.5에서 websocket을 사용하려고했습니다. 이제 여러 메시지 유형을 교환하고 싶습니다.복수 메시지 유형 - 스칼라가있는 프레임 워크의 websocket에 대한 액터
그러나 클라이언트가 websocket을 통해 json을 보내면 다음과 같은 오류가 발생합니다.
여러 메시지 유형을 교환하려면 다른 방법을 선택해야합니까?
누락되었거나 더 쉬운 방법이 있습니까?
[error] a.a.OneForOneStrategy - {"sort":"post", "to":"receiver","message":"Test"} (of class play.api.libs.json.JsObject)
scala.MatchError: {"sort":"post", "to":"receiver","message":"Test"} (of class play.api.libs.json.JsObject)
at controllers.MessageController$MessageActor$$anonfun$receive$1.applyOrElse(MessageController.scala:72)
at akka.actor.Actor$class.aroundReceive(Actor.scala:514)
at controllers.MessageController$MessageActor.aroundReceive(MessageController.scala:63)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:527)
at akka.actor.ActorCell.invoke(ActorCell.scala:496)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
models.scala
abstract class WSMessageIn()
// Classes for input
case class PostMessage(
sort: String = "post",
to: String,
...
message: Option[String] = None
) extends WSMessageIn
object PostMessage {
implicit val postMessageFormat = Json.format[PostMessage]
}
case class MessageFromIn(
sort: String = "receive",
from: String,
...
message: Option[String] = None
) extends WSMessageIn
object MessageFromIn {
implicit val messageFromInFormat = Json.format[MessageFromIn]
}
object WSMessageIn {
implicit def json2object(value: JsValue): WSMessageIn = {
(value \ "sort").as[String] match {
case "post" => value.as[PostMessage]
case "receive" => value.as[MessageFromIn]
}
}
implicit def object2json(in: WSMessageIn): JsValue = {
in match {
case in: PostMessage => Json.toJson(in)
case in: MessageFromIn => Json.toJson(in)
}
}
}
MessageController.scala
class MessageController @Inject() (
silhouette: Silhouette[DefaultEnv],
..
implicit val system: ActorSystem,
implicit val materializer: Materializer)
extends Controller {
class MessageActor(out: ActorRef) extends Actor {
override def receive = {
case message: JsValue =>
message match { // !!The error occurs here
case message: PostMessage =>
...
case message: MessageFromIn =>
...
}
}
}
object MessageActor {
def props(out: ActorRef) = Props(new MessageActor(out))
}
implicit val messageFlowTransformer = MessageFlowTransformer.jsonMessageFlowTransformer[JsValue, JsValue]
def socket() = WebSocket.acceptOrResult[JsValue, JsValue] { request =>
implicit val req = Request(request, AnyContentAsEmpty)
silhouette.SecuredRequestHandler { securedRequest =>
Future.successful(HandlerResult(Ok, Some(securedRequest.identity)))
}.map {
case HandlerResult(r, Some(user)) => Right(ActorFlow.actorRef(out => MessageActor.props(out)))
case HandlerResult(r, None) => Left(r)
}
}
}
으로 설정할 수 있습니다. 정말로 감사드립니다. 이것이 제가 알고 싶었던 것입니다. – Gianfrance