From c9dcfeb95a60179d79f979fadfa9a248b809e4dd Mon Sep 17 00:00:00 2001 From: Hoai Viet Nguyen <viet.nguyen@th-koeln.de> Date: Wed, 9 Apr 2025 11:48:56 +0200 Subject: [PATCH] add echo and simple chat --- build.gradle | 1 + .../websocketsdemo/configs/WebSocketConfig.kt | 17 ++++++++++ .../controllers/WelcomeController.kt | 17 ++++++++++ .../gm/websocketsdemo/handlers/EchoHandler.kt | 11 +++++++ .../handlers/SimpleChatHandler.kt | 26 +++++++++++++++ src/main/resources/static/echoclient.html | 32 +++++++++++++++++++ src/main/resources/templates/index.ftlh | 9 ++++++ src/main/resources/templates/layout.ftlh | 27 ++++++++++++++++ src/main/resources/templates/simpleChat.ftlh | 24 ++++++++++++++ 9 files changed, 164 insertions(+) create mode 100644 src/main/kotlin/de/thk/gm/websocketsdemo/configs/WebSocketConfig.kt create mode 100644 src/main/kotlin/de/thk/gm/websocketsdemo/controllers/WelcomeController.kt create mode 100644 src/main/kotlin/de/thk/gm/websocketsdemo/handlers/EchoHandler.kt create mode 100644 src/main/kotlin/de/thk/gm/websocketsdemo/handlers/SimpleChatHandler.kt create mode 100644 src/main/resources/static/echoclient.html create mode 100644 src/main/resources/templates/index.ftlh create mode 100644 src/main/resources/templates/layout.ftlh create mode 100644 src/main/resources/templates/simpleChat.ftlh diff --git a/build.gradle b/build.gradle index faa97d4..efa4a43 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,7 @@ dependencies { implementation 'org.jetbrains.kotlin:kotlin-reflect' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5' + developmentOnly 'org.springframework.boot:spring-boot-devtools' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/configs/WebSocketConfig.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/configs/WebSocketConfig.kt new file mode 100644 index 0000000..71ef4b1 --- /dev/null +++ b/src/main/kotlin/de/thk/gm/websocketsdemo/configs/WebSocketConfig.kt @@ -0,0 +1,17 @@ +package de.thk.gm.websocketsdemo.configs + +import de.thk.gm.websocketsdemo.handlers.EchoHandler +import de.thk.gm.websocketsdemo.handlers.SimpleChatHandler +import org.springframework.context.annotation.Configuration +import org.springframework.web.socket.config.annotation.EnableWebSocket +import org.springframework.web.socket.config.annotation.WebSocketConfigurer +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry + +@Configuration +@EnableWebSocket +class WebSocketConfig () : WebSocketConfigurer { + override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) { + registry.addHandler(EchoHandler(),"/echo") + registry.addHandler(SimpleChatHandler(),"/chat") + } +} \ No newline at end of file diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/controllers/WelcomeController.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/controllers/WelcomeController.kt new file mode 100644 index 0000000..eedc6ec --- /dev/null +++ b/src/main/kotlin/de/thk/gm/websocketsdemo/controllers/WelcomeController.kt @@ -0,0 +1,17 @@ +package de.thk.gm.websocketsdemo.controllers + +import org.springframework.stereotype.Controller +import org.springframework.web.bind.annotation.GetMapping + +@Controller +class WelcomeController { + @GetMapping("/") + fun index(): String { + return "index" + } + + @GetMapping("/simplechat") + fun simpleChat(): String { + return "simpleChat" + } +} \ No newline at end of file diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/handlers/EchoHandler.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/handlers/EchoHandler.kt new file mode 100644 index 0000000..a93ce45 --- /dev/null +++ b/src/main/kotlin/de/thk/gm/websocketsdemo/handlers/EchoHandler.kt @@ -0,0 +1,11 @@ +package de.thk.gm.websocketsdemo.handlers + +import org.springframework.web.socket.TextMessage +import org.springframework.web.socket.WebSocketSession +import org.springframework.web.socket.handler.TextWebSocketHandler + +class EchoHandler : TextWebSocketHandler() { + override fun handleTextMessage(session: WebSocketSession, message: TextMessage) { + session.sendMessage(message) + } +} \ No newline at end of file diff --git a/src/main/kotlin/de/thk/gm/websocketsdemo/handlers/SimpleChatHandler.kt b/src/main/kotlin/de/thk/gm/websocketsdemo/handlers/SimpleChatHandler.kt new file mode 100644 index 0000000..7bc632e --- /dev/null +++ b/src/main/kotlin/de/thk/gm/websocketsdemo/handlers/SimpleChatHandler.kt @@ -0,0 +1,26 @@ +package de.thk.gm.websocketsdemo.handlers + +import org.springframework.web.socket.* +import org.springframework.web.socket.handler.TextWebSocketHandler + +class SimpleChatHandler(): TextWebSocketHandler() { + private var sessions : ArrayList<WebSocketSession> = ArrayList() + override fun afterConnectionEstablished(session: WebSocketSession) { + sessions.add(session) + } + + override fun handleTextMessage(session: WebSocketSession, message: TextMessage) { + for (session in sessions) { + session.sendMessage(message) + } + } + + override fun afterConnectionClosed(session: WebSocketSession, status: CloseStatus) { + for (chatSession in sessions) { + if (chatSession.id == session.id) { + sessions.remove(chatSession) + } + } + + } +} \ No newline at end of file diff --git a/src/main/resources/static/echoclient.html b/src/main/resources/static/echoclient.html new file mode 100644 index 0000000..d1b7cb0 --- /dev/null +++ b/src/main/resources/static/echoclient.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Echo Demo</title> +</head> +<body> +<h1>Echo Demo</h1> +<input type="text" id="message"> +<button type="button" onclick="sendMessage()">Send</button> +<div id="echo"></div> +<a href="/">Back</a> +<script> + var ws = new WebSocket("/echo") + + ws.onopen = function (event) { + alert("WebSocket successfully established") + } + + function sendMessage(){ + var message = document.getElementById("message").value + ws.send(message) + } + + ws.onmessage = function (message) { + echo.innerHTML += "<p>" + message.data + "</p>" + } + +</script> +</body> +</html> \ No newline at end of file diff --git a/src/main/resources/templates/index.ftlh b/src/main/resources/templates/index.ftlh new file mode 100644 index 0000000..eb82bb2 --- /dev/null +++ b/src/main/resources/templates/index.ftlh @@ -0,0 +1,9 @@ +<#import "layout.ftlh" as base> +<#import "/spring.ftl" as spring /> +<@base.layout> + <ul> + <li><a href="/echoclient.html">Echo Client</a></li> + <li><a href="/simplechat">Simple Chat</a></li> + <li><a href="/chatrooms">Chat rooms</a></li> + </ul> +</@base.layout> diff --git a/src/main/resources/templates/layout.ftlh b/src/main/resources/templates/layout.ftlh new file mode 100644 index 0000000..ff32195 --- /dev/null +++ b/src/main/resources/templates/layout.ftlh @@ -0,0 +1,27 @@ +<#macro layout> + <!doctype html> + <html lang="en"> + <head> + <meta charset="UTF-8"> + <meta name="viewport" + content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + <meta http-equiv="X-UA-Compatible" content="ie=edge"> + <title>WebSocket Demos</title> + </head> + <body> + <header> + <h1>WebSocket Demos</h1> + </header> + <hr> + <main> + <#nested> + </main> + <hr> + <footer> + <a href="/#">Imprint</a> + <a href="/#">About Us</a> + <a href="/#">Privacy</a> + </footer> + </body> + </html> +</#macro> \ No newline at end of file diff --git a/src/main/resources/templates/simpleChat.ftlh b/src/main/resources/templates/simpleChat.ftlh new file mode 100644 index 0000000..75d821a --- /dev/null +++ b/src/main/resources/templates/simpleChat.ftlh @@ -0,0 +1,24 @@ +<#import "layout.ftlh" as base> +<@base.layout> + <h1>Simple Chat</h1> + <div id="chat"> + </div> + <input type="text" id="sender" placeholder="Max Mustermann"><br> + <input type="text" id="text" placeholder="Message..."> + <button type="button" onclick="sendMessage()">Send</button> + <script> + var ws = new WebSocket("/chat") + var chat = document.getElementById("chat") + ws.onmessage = function (message) { + var chatMessage = JSON.parse(message.data) + chat.innerHTML += "<p><b>" +chatMessage.sender+ "</b>:" + chatMessage.text + "</p>" + } + function sendMessage(){ + var text = document.getElementById("text").value + var sender = document.getElementById("sender").value + var chatMessage = {"sender": sender, "text":text} + ws.send(JSON.stringify(chatMessage)) + } + + </script> +</@base.layout> \ No newline at end of file -- GitLab