Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chatroom-dev-004-priave-msg-dev-1 #191

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;

// NOTE !!! DO NOT enable below, or will cause websocket connection error
//@ComponentScan(basePackages = "com.yen.springChatRoom.redis.RedisListenerBean") // https://blog.csdn.net/automal/article/details/111859409
// @ComponentScan(basePackages = "com.yen.springChatRoom.redis.RedisListenerBean") //
// https://blog.csdn.net/automal/article/details/111859409
@SpringBootApplication
public class ChatRoomApplication {

public static void main(String[] args) {

SpringApplication.run(ChatRoomApplication.class, args);
}
public static void main(String[] args) {

SpringApplication.run(ChatRoomApplication.class, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public class ChatMessage {
private MessageType type;
private String content;
private String sender;
private String receiver;

public MessageType getType() {
return type;
Expand All @@ -29,6 +30,14 @@ public void setSender(String sender) {
this.sender = sender;
}

public String getReceiver() {
return receiver;
}

public void setReceiver(String sender) {
this.receiver = receiver;
}

@Override
public String toString() {
return "ChatMessage{"
Expand All @@ -40,6 +49,9 @@ public String toString() {
+ ", sender='"
+ sender
+ '\''
+ ", receiver='"
+ receiver
+ '\''
+ '}';
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package com.yen.springChatRoom.controller;

import com.yen.springChatRoom.bean.ChatMessage;
import com.yen.springChatRoom.bean.Message;
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.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Slf4j
@Controller
Expand All @@ -34,6 +31,7 @@ public class ChatController {
@Autowired private RedisTemplate<String, String> redisTemplate;
@Autowired private SimpMessagingTemplate simpMessagingTemplate;


/** single mode : read msg from FE, and send to other users (@SendTo("/topic/public")) directly */
// @MessageMapping("/chat.sendMessage")
// @SendTo("/topic/public")
Expand Down Expand Up @@ -74,15 +72,22 @@ public void addUser(@Payload ChatMessage chatMessage, SimpMessageHeaderAccessor
}

// TODO : check @DestinationVariable ?
@RequestMapping("/app/private/{username}")
public void handlePrivateMessage(@DestinationVariable String username, Message message) {
// @RequestMapping("/app/private/{username}")
@MessageMapping("/chat.sendPrivateMessage") // This will be called when a user sends a message
public void handlePrivateMessage(@Payload ChatMessage chatMessage) {

log.info("handlePrivateMessage : username = " + 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);
// redisTemplate
// .opsForSet()
// .add(privateChannel + "." + username, JsonUtil.parseObjToJson(message));
// simpMessagingTemplate.convertAndSendToUser(username, "/topic/private", message);
// Send the message to the specific user
log.info(">>> chatMessage = " + chatMessage);
//log.info(">>> chatMessage.getReceiver() = " + chatMessage.getReceiver());
// TODO : fix below hardcode
simpMessagingTemplate.convertAndSendToUser(
"zzzz", "/queue/private", chatMessage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,32 @@
@RequestMapping("/user")
public class UserController {

private final String onlineUserKey = "websocket.onlineUsers";
@Value("${redis.channel.msgToAll}")
private String msgToAll;
@Value("${redis.set.onlineUsers}")
private String onlineUsers;
@Value("${redis.channel.userStatus}")
private String userStatus;
@Autowired
private RedisTemplate<String, String> redisTemplate;

@GetMapping("/online_user")
public List<String> getOnlineUser(){

Set<String> resultSet = redisTemplate.opsForSet().members(onlineUserKey);
log.info("(getOnlineUser) resultSet = " + resultSet);
// TODO : optimize below
OnlineUser onlineUser = new OnlineUser();
List<String> users = new ArrayList<>();
resultSet.forEach(x -> {
users.add(x);
});
onlineUser.setUsers(users);
return onlineUser.getUsers();
}
private final String onlineUserKey = "websocket.onlineUsers";

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

@Value("${redis.set.onlineUsers}")
private String onlineUsers;

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

@Autowired private RedisTemplate<String, String> redisTemplate;

@GetMapping("/online_user")
public List<String> getOnlineUser() {

Set<String> resultSet = redisTemplate.opsForSet().members(onlineUserKey);
log.info("(getOnlineUser) resultSet = " + resultSet);
// TODO : optimize below
OnlineUser onlineUser = new OnlineUser();
List<String> users = new ArrayList<>();
resultSet.forEach(
x -> {
users.add(x);
});
onlineUser.setUsers(users);
return onlineUser.getUsers();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,68 @@
@Component
public class WebSocketEventListener {

@Value("${server.port}")
private String serverPort;

@Value("${redis.set.onlineUsers}")
private String onlineUsers;

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

@Autowired
private RedisTemplate<String, String> redisTemplate;

@Autowired
private SimpMessageSendingOperations messagingTemplate;

// connect
// @EventListener
// public void handleWebSocketConnectListener(SessionConnectedEvent event){
//
// LOGGER.info("Receive a new web socket connection!");
// }
public void handleWebSocketConnectListener(SessionConnectedEvent event) {

InetAddress localHost;
try {
localHost = Inet4Address.getLocalHost();
log.info("Received a new web socket connection from:" + localHost.getHostAddress() + ":" + serverPort);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
@Value("${server.port}")
private String serverPort;

@Value("${redis.set.onlineUsers}")
private String onlineUsers;

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

// disconnect
@EventListener
public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
@Autowired private RedisTemplate<String, String> redisTemplate;

StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());
@Autowired private SimpMessageSendingOperations messagingTemplate;

String username = (String) headerAccessor.getSessionAttributes().get("username");
// connect
// @EventListener
// public void handleWebSocketConnectListener(SessionConnectedEvent event){
//
// LOGGER.info("Receive a new web socket connection!");
// }
public void handleWebSocketConnectListener(SessionConnectedEvent event) {

if (username != null) {
log.info("User Disconnected : " + username);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessage.MessageType.LEAVE);
chatMessage.setSender(username);
try {
redisTemplate.opsForSet().remove(onlineUsers, username);
redisTemplate.convertAndSend(userStatus, JsonUtil.parseObjToJson(chatMessage));
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
InetAddress localHost;
try {
localHost = Inet4Address.getLocalHost();
log.info(
"Received a new web socket connection from:"
+ localHost.getHostAddress()
+ ":"
+ serverPort);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}

// disconnect
@EventListener
public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {

StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());

log.info(">>> (handleWebSocketDisconnectListener) headerAccessor = " + headerAccessor);

String username = (String) headerAccessor.getSessionAttributes().get("username");
String receiver = (String) headerAccessor.getSessionAttributes().get("receiver");

if (username != null) {
log.info("User Disconnected : " + username);
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessage.MessageType.LEAVE);
chatMessage.setSender(username);

// TODO : double check ??? (for private chat)
if (receiver != null) {
chatMessage.setReceiver(receiver);
}

try {
redisTemplate.opsForSet().remove(onlineUsers, username);
redisTemplate.convertAndSend(userStatus, JsonUtil.parseObjToJson(chatMessage));
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,38 @@
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.stereotype.Component;

/**
* Class for Redis channel conn
*/
/** Class for Redis channel conn */
@Slf4j
@Component
public class RedisListenerBean {

// read setting from config
@Value("${server.port}")
private String serverPort;

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

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

/**
* Redis channel bean
* <p>
* 1. listen Redis channel via binding (for example : container.addMessageListener)
* 2. can do further biz logic in method
*/
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {

RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);

// listen msgToAll (Redis channel)
container.addMessageListener(listenerAdapter, new PatternTopic(msgToAll));
container.addMessageListener(listenerAdapter, new PatternTopic(userStatus));
log.info("Subscribe Redis channel : " + msgToAll);
return container;
}

// read setting from config
@Value("${server.port}")
private String serverPort;

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

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

/**
* Redis channel bean
*
* <p>1. listen Redis channel via binding (for example : container.addMessageListener) 2. can do
* further biz logic in method
*/
@Bean
RedisMessageListenerContainer container(
RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {

RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);

// listen msgToAll (Redis channel)
container.addMessageListener(listenerAdapter, new PatternTopic(msgToAll));
container.addMessageListener(listenerAdapter, new PatternTopic(userStatus));
log.info("Subscribe Redis channel : " + msgToAll);
return container;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.yen.springChatRoom.service;

import com.yen.springChatRoom.bean.ChatMessage;
import com.yen.springChatRoom.controller.ChatController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Payload;
Expand Down
Loading