95 lines
2.5 KiB
Scala
95 lines
2.5 KiB
Scala
package model.sessions
|
|
|
|
import de.knockoutwhist.utils.events.SimpleEvent
|
|
import org.apache.pekko.actor.{Actor, ActorRef}
|
|
import play.api.libs.json.{JsObject, JsValue, Json}
|
|
import util.WebsocketEventMapper
|
|
|
|
import scala.util.{Failure, Success, Try}
|
|
|
|
class UserWebsocketActor(
|
|
out: ActorRef,
|
|
session: UserSession
|
|
) extends Actor {
|
|
|
|
if (session.websocketActor.isDefined) {
|
|
session.websocketActor.foreach(actor => actor.transmitTextToClient("Error: Multiple websocket connections detected. Closing this connection."))
|
|
context.stop(self)
|
|
} else {
|
|
session.websocketActor = Some(this)
|
|
}
|
|
|
|
override def receive: Receive = {
|
|
case msg: String =>
|
|
val jsonObject = Try {
|
|
Json.parse(msg)
|
|
}
|
|
Try {
|
|
jsonObject match {
|
|
case Success(value) =>
|
|
handle(value)
|
|
case Failure(exception) =>
|
|
transmitTextToClient(s"Error parsing JSON: ${exception.getMessage}")
|
|
}
|
|
}.failed.foreach(
|
|
ex => transmitTextToClient(s"Error handling message: ${ex.getMessage}")
|
|
)
|
|
case other =>
|
|
}
|
|
|
|
def transmitEventToClient(event: SimpleEvent): Unit = {
|
|
val jsonString = WebsocketEventMapper.toJsonString(event)
|
|
out ! jsonString
|
|
}
|
|
|
|
private def transmitJsonToClient(jsonObj: JsObject): Unit = {
|
|
out ! jsonObj.toString()
|
|
}
|
|
|
|
private def transmitTextToClient(text: String): Unit = {
|
|
out ! text
|
|
}
|
|
|
|
private def handle(json: JsValue): Unit = {
|
|
val idOpt = (json \ "id").asOpt[String]
|
|
if (idOpt.isEmpty) {
|
|
transmitJsonToClient(Json.obj(
|
|
"status" -> "error",
|
|
"error" -> "Missing 'id' field"
|
|
))
|
|
return
|
|
}
|
|
val id = idOpt.get
|
|
val eventOpt = (json \ "event").asOpt[String]
|
|
if (eventOpt.isEmpty) {
|
|
transmitJsonToClient(Json.obj(
|
|
"id" -> id,
|
|
"event" -> null,
|
|
"status" -> "error",
|
|
"error" -> "Missing 'event' field"
|
|
))
|
|
return
|
|
}
|
|
val event = eventOpt.get
|
|
val data = (json \ "data").asOpt[JsObject].getOrElse(Json.obj())
|
|
val result = Try {
|
|
session.handleWebResponse(event, data)
|
|
}
|
|
if (result.isSuccess) {
|
|
transmitJsonToClient(Json.obj(
|
|
"id" -> id,
|
|
"event" -> event,
|
|
"status" -> "success"
|
|
))
|
|
} else {
|
|
transmitJsonToClient(Json.obj(
|
|
"id" -> id,
|
|
"event" -> event,
|
|
"status" -> "error",
|
|
"error" -> result.failed.get.getMessage
|
|
))
|
|
}
|
|
}
|
|
|
|
}
|