Skip to content
Snippets Groups Projects
Commit 26e8e691 authored by Hoai Viet Nguyen's avatar Hoai Viet Nguyen
Browse files

add chatrooms

parent d11ed0b8
No related branches found
No related tags found
No related merge requests found
Showing
with 205 additions and 0 deletions
...@@ -24,9 +24,13 @@ dependencies { ...@@ -24,9 +24,13 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-websocket' implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin' implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
implementation 'org.jetbrains.kotlin:kotlin-reflect' implementation 'org.jetbrains.kotlin:kotlin-reflect'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5' testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5'
developmentOnly 'org.springframework.boot:spring-boot-devtools' developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'org.postgresql:postgresql'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
} }
......
package de.thk.gm.websocketsdemo.configs package de.thk.gm.websocketsdemo.configs
import de.thk.gm.websocketsdemo.handlers.ChatRoomsHandler
import de.thk.gm.websocketsdemo.handlers.EchoHandler import de.thk.gm.websocketsdemo.handlers.EchoHandler
import de.thk.gm.websocketsdemo.handlers.SimpleChatHandler import de.thk.gm.websocketsdemo.handlers.SimpleChatHandler
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
...@@ -14,5 +15,6 @@ class WebSocketsConfig(): WebSocketConfigurer { ...@@ -14,5 +15,6 @@ class WebSocketsConfig(): WebSocketConfigurer {
override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) { override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
registry.addHandler(EchoHandler(), "/echo").setAllowedOrigins("*") registry.addHandler(EchoHandler(), "/echo").setAllowedOrigins("*")
registry.addHandler(SimpleChatHandler(), "/chat") registry.addHandler(SimpleChatHandler(), "/chat")
registry.addHandler(ChatRoomsHandler(),"/rooms")
} }
} }
\ No newline at end of file
package de.thk.gm.websocketsdemo.controllers
import de.thk.gm.websocketsdemo.dtos.ChatRoomDto
import de.thk.gm.websocketsdemo.models.ChatRoom
import de.thk.gm.websocketsdemo.services.ChatRoomsService
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.*
import java.util.*
@Controller
@RequestMapping("/chatrooms")
class ChatRoomsController (private val chatRoomsService: ChatRoomsService) {
@GetMapping
fun getChatRooms(model: Model): String {
model.addAttribute("chatRooms", chatRoomsService.getChatRooms())
return "chatRooms/showChatRooms"
}
@PostMapping
fun addChatRoom(chatRoomDto: ChatRoomDto): String {
var chatRoom = ChatRoom()
chatRoom.name = chatRoomDto.name
chatRoomsService.save(chatRoom)
return "redirect:/chatrooms/${chatRoom.id}"
}
@GetMapping("/{id}")
fun getChatRoom(@PathVariable("id") id: UUID, model: Model): String {
var chatRoom = chatRoomsService.getChatRoomById(id)
model.addAttribute("chatRoom", chatRoom)
return "chatRooms/showChatRoom"
}
}
\ No newline at end of file
package de.thk.gm.websocketsdemo.dtos
import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Size
class ChatRoomDto {
@NotNull
@Size(min = 1, max = 50)
var name: String = ""
}
\ No newline at end of file
package de.thk.gm.websocketsdemo.handlers
import org.springframework.web.socket.CloseStatus
import org.springframework.web.socket.TextMessage
import org.springframework.web.socket.WebSocketSession
import org.springframework.web.socket.handler.TextWebSocketHandler
import org.springframework.web.util.UriComponents
import org.springframework.web.util.UriComponentsBuilder
class ChatRoomsHandler : TextWebSocketHandler() {
private val hashMapOfSessions : HashMap<String, ArrayList<WebSocketSession>> = HashMap()
override fun afterConnectionEstablished(session: WebSocketSession) {
var uri : UriComponents = UriComponentsBuilder.fromUri(session.uri!!).build()
var id = uri.queryParams.getFirst("id")
if(id != null) {
var sessions = hashMapOfSessions[id]
if(sessions == null) {
sessions = ArrayList()
}
sessions.add(session)
hashMapOfSessions[id] = sessions
}
}
override fun handleTextMessage(session: WebSocketSession, message: TextMessage) {
var uri : UriComponents = UriComponentsBuilder.fromUri(session.uri!!).build()
var id = uri.queryParams.getFirst("id")
var sessions = hashMapOfSessions[id]
if(sessions != null) {
for (chatSession in sessions) {
chatSession.sendMessage(message)
}
}
}
override fun afterConnectionClosed(session: WebSocketSession, status: CloseStatus) {
var uri : UriComponents = UriComponentsBuilder.fromUri(session.uri!!).build()
var id = uri.queryParams.getFirst("id")
var sessions = hashMapOfSessions[id]
if(sessions != null) {
sessions.remove(session)
}
}
}
\ No newline at end of file
package de.thk.gm.websocketsdemo.models
import jakarta.persistence.Entity
import jakarta.persistence.Id
import java.util.*
@Entity
class ChatRoom {
@Id
var id : UUID = UUID.randomUUID()
var name: String = ""
}
\ No newline at end of file
package de.thk.gm.websocketsdemo.repositories
import de.thk.gm.websocketsdemo.models.ChatRoom
import org.springframework.data.repository.CrudRepository
import org.springframework.stereotype.Repository
import java.util.*
@Repository
interface ChatRoomsRepository : CrudRepository<ChatRoom, UUID> {
}
\ No newline at end of file
package de.thk.gm.websocketsdemo.services
import de.thk.gm.websocketsdemo.models.ChatRoom
import java.util.*
interface ChatRoomsService {
fun getChatRooms(): List<ChatRoom>
fun getChatRoomById(id: UUID): ChatRoom?
fun save(chatRoom: ChatRoom)
}
\ No newline at end of file
package de.thk.gm.websocketsdemo.services
import de.thk.gm.websocketsdemo.models.ChatRoom
import de.thk.gm.websocketsdemo.repositories.ChatRoomsRepository
import org.springframework.stereotype.Service
import java.util.*
@Service
class ChatRoomsServiceImpl (private val chatRoomsRepository: ChatRoomsRepository) : ChatRoomsService {
override fun getChatRooms(): List<ChatRoom> {
return chatRoomsRepository.findAll().toList()
}
override fun getChatRoomById(id: UUID): ChatRoom? {
return chatRoomsRepository.findById(id).orElse(null)
}
override fun save(chatRoom: ChatRoom) {
chatRoomsRepository.save(chatRoom)
}
}
\ No newline at end of file
<!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>Chat Room</title>
</head>
<body>
<h1>Chat room ${chatRoom.name}</h1>
<input type="text" id="username" placeholder="username">
<input type="text" id="text" placeholder="message">
<br>
<button onclick="sendMessage()">Send</button>
<div id="chat"></div>
<script>
var ws = new WebSocket("/rooms?id=${chatRoom.id}")
var chat = document.getElementById("chat")
var message = {}
function sendMessage(){
message.username = document.getElementById("username").value
message.text = document.getElementById("text").value
ws.send(JSON.stringify(message))
}
ws.onmessage = function (msg) {
message = JSON.parse(msg.data)
chat.innerHTML += "<p><b>"+message.username+":</b>" + message.text + "</p>"
}
</script>
</body>
</html>
\ No newline at end of file
<!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>Chat Rooms</title>
</head>
<body>
<h1>Chat Rooms</h1>
<ul>
<#list chatRooms as room>
<li><a href="/chatrooms/${room.id}">${room.name}</a></li>
</#list>
</ul><br>
<form action="/chatrooms" method="post">
<input name="name" type="text"><br>
<button>Create chat room</button>
</form>
</body>
</html>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment