From 3073bca3508d51b45e282a3ade72a9da8069cf62 Mon Sep 17 00:00:00 2001 From: Pasindu Owa Gamage Date: Sat, 11 Apr 2026 20:07:17 +0530 Subject: [PATCH 1/2] feat: Implement WebSocket chat functionality with message handling and storage --- .../eventsphere/config/WebSocketConfig.java | 23 +++++++++++++++++ .../controller/ChatController.java | 22 ++++++++++++++++ .../eventsphere/dto/ChatMessageRequest.java | 4 +++ .../eventsphere/dto/ChatMessageResponse.java | 6 +++++ .../repository/ChatMessageRepository.java | 7 ++++++ .../impl/ChatMessageRepositoryImpl.java | 25 +++++++++++++++++++ .../service/ChatMessageService.java | 8 ++++++ .../service/impl/ChatMessageServiceImpl.java | 19 ++++++++++++++ 8 files changed, 114 insertions(+) create mode 100644 src/main/java/dev/pasinduog/eventsphere/config/WebSocketConfig.java create mode 100644 src/main/java/dev/pasinduog/eventsphere/controller/ChatController.java create mode 100644 src/main/java/dev/pasinduog/eventsphere/dto/ChatMessageRequest.java create mode 100644 src/main/java/dev/pasinduog/eventsphere/dto/ChatMessageResponse.java create mode 100644 src/main/java/dev/pasinduog/eventsphere/repository/ChatMessageRepository.java create mode 100644 src/main/java/dev/pasinduog/eventsphere/repository/impl/ChatMessageRepositoryImpl.java create mode 100644 src/main/java/dev/pasinduog/eventsphere/service/ChatMessageService.java create mode 100644 src/main/java/dev/pasinduog/eventsphere/service/impl/ChatMessageServiceImpl.java diff --git a/src/main/java/dev/pasinduog/eventsphere/config/WebSocketConfig.java b/src/main/java/dev/pasinduog/eventsphere/config/WebSocketConfig.java new file mode 100644 index 0000000..1b96dbc --- /dev/null +++ b/src/main/java/dev/pasinduog/eventsphere/config/WebSocketConfig.java @@ -0,0 +1,23 @@ +package dev.pasinduog.eventsphere.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws-event-chat").setAllowedOrigins("*"); + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.setApplicationDestinationPrefixes("/app"); + registry.enableSimpleBroker("/topic"); + } +} diff --git a/src/main/java/dev/pasinduog/eventsphere/controller/ChatController.java b/src/main/java/dev/pasinduog/eventsphere/controller/ChatController.java new file mode 100644 index 0000000..63cb227 --- /dev/null +++ b/src/main/java/dev/pasinduog/eventsphere/controller/ChatController.java @@ -0,0 +1,22 @@ +package dev.pasinduog.eventsphere.controller; + +import dev.pasinduog.eventsphere.dto.ChatMessageRequest; +import dev.pasinduog.eventsphere.dto.ChatMessageResponse; +import dev.pasinduog.eventsphere.service.ChatMessageService; +import lombok.RequiredArgsConstructor; +import org.springframework.messaging.handler.annotation.DestinationVariable; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.stereotype.Controller; + +@Controller +@RequiredArgsConstructor +public class ChatController { + private final ChatMessageService chatMessageService; + + @MessageMapping("/chat/{eventId}") + @SendTo("/topic/events/{eventId}") + ChatMessageResponse sendMessage(@DestinationVariable String eventId, ChatMessageRequest request) { + return chatMessageService.saveMessage(eventId, request); + } +} diff --git a/src/main/java/dev/pasinduog/eventsphere/dto/ChatMessageRequest.java b/src/main/java/dev/pasinduog/eventsphere/dto/ChatMessageRequest.java new file mode 100644 index 0000000..e1d9716 --- /dev/null +++ b/src/main/java/dev/pasinduog/eventsphere/dto/ChatMessageRequest.java @@ -0,0 +1,4 @@ +package dev.pasinduog.eventsphere.dto; + +public record ChatMessageRequest(String senderId, String message) { +} diff --git a/src/main/java/dev/pasinduog/eventsphere/dto/ChatMessageResponse.java b/src/main/java/dev/pasinduog/eventsphere/dto/ChatMessageResponse.java new file mode 100644 index 0000000..1de436f --- /dev/null +++ b/src/main/java/dev/pasinduog/eventsphere/dto/ChatMessageResponse.java @@ -0,0 +1,6 @@ +package dev.pasinduog.eventsphere.dto; + +import java.time.LocalDateTime; + +public record ChatMessageResponse(String id, String eventId, String senderId, String message, LocalDateTime sentAt) { +} diff --git a/src/main/java/dev/pasinduog/eventsphere/repository/ChatMessageRepository.java b/src/main/java/dev/pasinduog/eventsphere/repository/ChatMessageRepository.java new file mode 100644 index 0000000..ad31f6e --- /dev/null +++ b/src/main/java/dev/pasinduog/eventsphere/repository/ChatMessageRepository.java @@ -0,0 +1,7 @@ +package dev.pasinduog.eventsphere.repository; + +import dev.pasinduog.eventsphere.dto.ChatMessageResponse; + +public interface ChatMessageRepository { + ChatMessageResponse saveMessage(String eventId, String senderId, String message); +} diff --git a/src/main/java/dev/pasinduog/eventsphere/repository/impl/ChatMessageRepositoryImpl.java b/src/main/java/dev/pasinduog/eventsphere/repository/impl/ChatMessageRepositoryImpl.java new file mode 100644 index 0000000..e4bd22c --- /dev/null +++ b/src/main/java/dev/pasinduog/eventsphere/repository/impl/ChatMessageRepositoryImpl.java @@ -0,0 +1,25 @@ +package dev.pasinduog.eventsphere.repository.impl; + +import dev.pasinduog.eventsphere.dto.ChatMessageResponse; +import dev.pasinduog.eventsphere.repository.ChatMessageRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Repository +@RequiredArgsConstructor +public class ChatMessageRepositoryImpl implements ChatMessageRepository { + private final JdbcTemplate jdbcTemplate; + + @Override + public ChatMessageResponse saveMessage(String eventId, String senderId, String message) { + String id = UUID.randomUUID().toString(); + LocalDateTime sentAt = LocalDateTime.now(); + String sql = "INSERT INTO chat_messages (id, event_id, sender_id, message, sent_at) VALUES (?,?,?,?,?)"; + jdbcTemplate.update(sql, id, eventId, senderId, message, sentAt); + return new ChatMessageResponse(id, eventId, senderId, message, sentAt); + } +} diff --git a/src/main/java/dev/pasinduog/eventsphere/service/ChatMessageService.java b/src/main/java/dev/pasinduog/eventsphere/service/ChatMessageService.java new file mode 100644 index 0000000..4354506 --- /dev/null +++ b/src/main/java/dev/pasinduog/eventsphere/service/ChatMessageService.java @@ -0,0 +1,8 @@ +package dev.pasinduog.eventsphere.service; + +import dev.pasinduog.eventsphere.dto.ChatMessageRequest; +import dev.pasinduog.eventsphere.dto.ChatMessageResponse; + +public interface ChatMessageService { + ChatMessageResponse saveMessage(String eventId, ChatMessageRequest request); +} diff --git a/src/main/java/dev/pasinduog/eventsphere/service/impl/ChatMessageServiceImpl.java b/src/main/java/dev/pasinduog/eventsphere/service/impl/ChatMessageServiceImpl.java new file mode 100644 index 0000000..cc0d66b --- /dev/null +++ b/src/main/java/dev/pasinduog/eventsphere/service/impl/ChatMessageServiceImpl.java @@ -0,0 +1,19 @@ +package dev.pasinduog.eventsphere.service.impl; + +import dev.pasinduog.eventsphere.dto.ChatMessageRequest; +import dev.pasinduog.eventsphere.dto.ChatMessageResponse; +import dev.pasinduog.eventsphere.repository.ChatMessageRepository; +import dev.pasinduog.eventsphere.service.ChatMessageService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class ChatMessageServiceImpl implements ChatMessageService { + private final ChatMessageRepository chatMessageRepository; + + @Override + public ChatMessageResponse saveMessage(String eventId, ChatMessageRequest request) { + return chatMessageRepository.saveMessage(eventId, request.senderId(), request.message()); + } +} From a7664423961fbb02eee34e1b4a1ed64e8f2b677f Mon Sep 17 00:00:00 2001 From: Pasindu Owa Gamage Date: Sat, 11 Apr 2026 20:57:04 +0530 Subject: [PATCH 2/2] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../eventsphere/service/impl/ChatMessageServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/dev/pasinduog/eventsphere/service/impl/ChatMessageServiceImpl.java b/src/main/java/dev/pasinduog/eventsphere/service/impl/ChatMessageServiceImpl.java index cc0d66b..5a6c8b3 100644 --- a/src/main/java/dev/pasinduog/eventsphere/service/impl/ChatMessageServiceImpl.java +++ b/src/main/java/dev/pasinduog/eventsphere/service/impl/ChatMessageServiceImpl.java @@ -5,9 +5,9 @@ import dev.pasinduog.eventsphere.repository.ChatMessageRepository; import dev.pasinduog.eventsphere.service.ChatMessageService; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Repository; +import org.springframework.stereotype.Service; -@Repository +@Service @RequiredArgsConstructor public class ChatMessageServiceImpl implements ChatMessageService { private final ChatMessageRepository chatMessageRepository;