Skip to content

Commit

Permalink
Merge pull request #119 from yennanliu/chatroom-dev-003-user-user-chat
Browse files Browse the repository at this point in the history
chatroom-dev-003-user-user-chat
  • Loading branch information
yennanliu authored Nov 27, 2023
2 parents 99242c0 + 04e79a9 commit d19396e
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 14 deletions.
6 changes: 6 additions & 0 deletions springChatRoom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@
<scope>test</scope>
</dependency>

<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.yen.springChatRoom.model;
package com.yen.springChatRoom.bean;

public class ChatMessage {
private MessageType type;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.yen.springChatRoom.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Message {

private String sender;
private String content;
private String type;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.yen.springChatRoom.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
Expand Down Expand Up @@ -28,7 +30,16 @@ public void registerStompEndpoints(StompEndpointRegistry registry) {
public void configureMessageBroker(MessageBrokerRegistry registry) {

//WebSocketMessageBrokerConfigurer.super.configureMessageBroker(registry);
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app"); // (client -> server)
registry.enableSimpleBroker("/topic", "/private"); // (server -> client)
}

//
// @Bean
// public SimpMessagingTemplate messagingTemplate() {
//
// //return new SimpMessagingTemplate(/* your message broker relay, e.g., "/topic" */);
// return new SimpMessagingTemplate("/private/");
// }

}
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
package com.yen.springChatRoom.controller;

import com.yen.springChatRoom.model.ChatMessage;
import com.yen.springChatRoom.bean.Message;
import com.yen.springChatRoom.bean.ChatMessage;
import com.yen.springChatRoom.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Set;
import org.springframework.web.bind.annotation.RequestMapping;

@Slf4j
@Controller
public class ChatController {

Expand All @@ -28,13 +30,19 @@ public class ChatController {
@Value("${redis.channel.userStatus}")
private String userStatus;

@Value("${redis.channel.private}")
private String privateChannel;

final String onlineUserKey = "websocket.onlineUsers";

// TODO : check difference ? RedisTemplate VS RedisTemplate<String, String>
@Autowired
private RedisTemplate<String, String> redisTemplate;
//private RedisTemplate redisTemplate;

@Autowired
private SimpMessagingTemplate simpMessagingTemplate;

private static final Logger LOGGER = LoggerFactory.getLogger(ChatController.class);

/**
Expand All @@ -56,6 +64,9 @@ public class ChatController {
@MessageMapping("/chat.sendMessage")
public void sendMessage(@Payload ChatMessage chatMessage){
try{

// test : save msg to redis
redisTemplate.opsForSet().add(msgToAll, JsonUtil.parseObjToJson(chatMessage));
//redisTemplate.convertAndSend(msgToAll, JsonUtil.parseObjToJson(chatMessage)));
redisTemplate.convertAndSend(msgToAll, JsonUtil.parseObjToJson(chatMessage));
}catch (Exception e){
Expand All @@ -79,4 +90,17 @@ public void addUser(@Payload ChatMessage chatMessage, SimpMessageHeaderAccessor
}
}

// TODO : check @DestinationVariable ?
@RequestMapping("/app/private/{username}")
public void handlePrivateMessage(@DestinationVariable String username, Message message){

log.info("handlePrivateMessage : username = " + username + " message = " + message);
// save to redis

// redisTemplate.convertAndSend(userStatus, JsonUtil.parseObjToJson(chatMessage));
redisTemplate.opsForSet().add(privateChannel + "." + username, JsonUtil.parseObjToJson(message));

simpMessagingTemplate.convertAndSendToUser(username, "/topic/private", message);
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.yen.springChatRoom.listener;

import com.yen.springChatRoom.controller.ChatController;
import com.yen.springChatRoom.model.ChatMessage;
import com.yen.springChatRoom.bean.ChatMessage;
import com.yen.springChatRoom.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.yen.springChatRoom.redis;

import com.yen.springChatRoom.model.ChatMessage;
import com.yen.springChatRoom.bean.ChatMessage;
import com.yen.springChatRoom.service.ChatService;
import com.yen.springChatRoom.util.JsonUtil;
import org.slf4j.Logger;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.yen.springChatRoom.service;

import com.yen.springChatRoom.controller.ChatController;
import com.yen.springChatRoom.model.ChatMessage;
import com.yen.springChatRoom.bean.ChatMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler;
import org.springframework.stereotype.Service;

@Service
Expand Down
2 changes: 2 additions & 0 deletions springChatRoom/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ server.port=8080
redis.set.onlineUsers = websocket.onlineUsers
redis.channel.msgToAll = websocket.msgToAll
redis.channel.userStatus = websocket.userStatus
redis.channel.private = websocket.privateMsg

31 changes: 29 additions & 2 deletions springChatRoom/src/main/resources/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ function connect(event) {


function onConnected() {

// Subscribe to the Public Topic
stompClient.subscribe('/topic/public', onMessageReceived);

// Subscribe to the "/private" destination // TODO : make it general
//stompClient.subscribe('/private/user123', onPrivateMessageReceived);

// Tell your username to the server
stompClient.send("/app/chat.addUser",
{},
Expand Down Expand Up @@ -158,7 +162,6 @@ function updateOnlineUsers(users) {
// Append the username span to the list item
listItem.appendChild(usernameSpan);


// Create a "Chat" button
const chatButton = document.createElement('button');
chatButton.textContent = 'Chat';
Expand All @@ -167,7 +170,6 @@ function updateOnlineUsers(users) {
// Append the "Chat" button to the list item
listItem.appendChild(chatButton);


// Append the list item to the user list
userList.appendChild(listItem);
});
Expand All @@ -189,6 +191,8 @@ function startChat(username) {

// Function to send a message from the popup window
popupWindow.sendMessage = function() {

console.log(">>> popupWindow.sendMessage")
const messageInput = popupWindow.document.getElementById('messageInput');
const chatMessages = popupWindow.document.getElementById('chatMessages');

Expand All @@ -197,15 +201,38 @@ function startChat(username) {
// Customize the way messages are displayed in the popup window
chatMessages.innerHTML += '<p><strong>You:</strong> ' + message + '</p>';

// TODO: Fetch and display chat history
//fetchChatHistory(username, chatMessages);

// TODO : implement below in BE
// Add your logic to send the message to the other user
// Example: stompClient.send('/app/private/' + username, {}, JSON.stringify({ sender: 'You', content: message, type: 'CHAT' }));

// send msg to BE
//stompClient.subscribe('/app/private/' + username, onPrivateMessageReceived);
stompClient.subscribe('/app/private/' + username);
console.log(">>> send msg to /app/private/" + username + ", message = " + message);
stompClient.send('/app/private/' + username, {}, JSON.stringify({ sender: 'You', content: message, type: 'CHAT' }));

// Clear the input field
messageInput.value = '';
}
};
}

// Function to fetch and display chat history
function fetchChatHistory(username, chatMessages) {
fetch('/app/chat/history/' + username)
.then(response => response.json())
.then(history => {
history.forEach(message => {
chatMessages.innerHTML += '<p><strong>' + message.sender + ':</strong> ' + message.content + '</p>';
});
})
.catch(error => {
console.error('Error fetching chat history: ', error);
});
}


// Call the fetchUserList function to initially populate the user list
Expand Down

0 comments on commit d19396e

Please sign in to comment.