From 09cc96141d38d9b04907f149dcb9c9c8d9cba804 Mon Sep 17 00:00:00 2001 From: LQ63 Date: Fri, 21 Nov 2025 17:11:16 +0100 Subject: [PATCH] feat(ui): Websocket Added simple websocket. Serverside websocket logic isnt in the usersession --- .../assets/actor/KnockOutWebSocketActor.scala | 21 +++++++++++++ .../app/controllers/WebsocketController.scala | 30 +++++++++++++++++++ knockoutwhistweb/conf/routes | 5 +++- knockoutwhistweb/public/javascripts/main.js | 19 ++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 knockoutwhistweb/app/assets/actor/KnockOutWebSocketActor.scala create mode 100644 knockoutwhistweb/app/controllers/WebsocketController.scala diff --git a/knockoutwhistweb/app/assets/actor/KnockOutWebSocketActor.scala b/knockoutwhistweb/app/assets/actor/KnockOutWebSocketActor.scala new file mode 100644 index 0000000..ce496de --- /dev/null +++ b/knockoutwhistweb/app/assets/actor/KnockOutWebSocketActor.scala @@ -0,0 +1,21 @@ +package actor + +import org.apache.pekko.actor.{Actor, ActorRef} +import org.apache.pekko.http.scaladsl.model.ContentRange.Other + + +class KnockOutWebSocketActor( + out: ActorRef, + ) extends Actor { + def receive: Receive = { + case msg: String => + out ! s"Received your message: ${msg}" + case other: Other => + println(s"Received unknown message: $other") + } + + def sendJsonToClient(json: String): Unit = { + println("Received event from Controller") + out ! json + } +} diff --git a/knockoutwhistweb/app/controllers/WebsocketController.scala b/knockoutwhistweb/app/controllers/WebsocketController.scala new file mode 100644 index 0000000..f35c49b --- /dev/null +++ b/knockoutwhistweb/app/controllers/WebsocketController.scala @@ -0,0 +1,30 @@ +package controllers +import actor.KnockOutWebSocketActor +import org.apache.pekko.actor.{ActorRef, ActorSystem, Props} +import org.apache.pekko.stream.Materializer +import play.api.* +import play.api.libs.streams.ActorFlow +import play.api.mvc.* + +import javax.inject.* + + +@Singleton +class WebsocketController @Inject()( + cc: ControllerComponents, + )(implicit system: ActorSystem, mat: Materializer) extends AbstractController(cc) { + + object KnockOutWebSocketActorFactory { + def create(out: ActorRef) = { + Props(new KnockOutWebSocketActor(out)) + } + } + def socket() = WebSocket.accept[String, String] { request => + ActorFlow.actorRef { out => + println("Connect received") + KnockOutWebSocketActorFactory.create(out) + } + } + + +} \ No newline at end of file diff --git a/knockoutwhistweb/conf/routes b/knockoutwhistweb/conf/routes index 267bab3..0584792 100644 --- a/knockoutwhistweb/conf/routes +++ b/knockoutwhistweb/conf/routes @@ -38,4 +38,7 @@ POST /game/:id/dogPlayCard controllers.IngameController.playDog POST /game/:id/returnToLobby controllers.IngameController.returnToLobby(id: String) # Polling -GET /polling/:gameId controllers.PollingController.polling(gameId: String) \ No newline at end of file +GET /polling/:gameId controllers.PollingController.polling(gameId: String) + +# Websocket +GET /websocket controllers.WebsocketController.socket() \ No newline at end of file diff --git a/knockoutwhistweb/public/javascripts/main.js b/knockoutwhistweb/public/javascripts/main.js index 1f8f830..5a3c436 100644 --- a/knockoutwhistweb/public/javascripts/main.js +++ b/knockoutwhistweb/public/javascripts/main.js @@ -664,4 +664,23 @@ function sendPlayCardRequest(jsonObj, gameId, cardobject, dog) { }) }) } +const ws = new WebSocket("ws://localhost:9000/websocket"); +ws.onopen = (event) => { + console.log("WebSocket connection established!"); + + ws.send("Client is now connected and ready."); +}; +ws.onmessage = (event) => { + console.log("SERVER RESPONSE:", event.data); +}; +ws.onerror = (error) => { + console.error("WebSocket Error:", error); +}; +ws.onclose = (event) => { + if (event.wasClean) { + console.log(`Connection closed cleanly, code=${event.code} reason=${event.reason}`); + } else { + console.warn('Connection died unexpectedly.'); + } +};