Skip to content

chatroom-dev-002-add-channel : add private channel (dev) #118

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

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
31 changes: 31 additions & 0 deletions .github/workflows/maven_chatroom.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: (ChatRoom service) Java CI with Maven

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: rm -rf ~/.m2 && cd springChatRoom && mvn -DskipTests=true package
5 changes: 4 additions & 1 deletion springChatRoom/doc/ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
- Advanced
- Chat with specific user
- https://www.baeldung.com/spring-websockets-send-message-to-user
- https://www.baeldung.com/spring-websockets-sendtouser

- https://github.com/eugenp/tutorials/tree/master/spring-security-modules/spring-security-web-sockets - code
- https://juejin.cn/post/6844903717636947981

- https://www.jb51.net/article/257091.htm
- https://www.jb51.net/article/257091.htm
- https://blog.csdn.net/xm393392625/article/details/103385509
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

// 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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.yen.springChatRoom.bean;

import java.util.List;

public class Channel {

private String channelId;
private List<User> users;

public Channel() {
}

public Channel(String channelId, List<User> users) {
this.channelId = channelId;
this.users = users;
}

public String getChannelId() {
return channelId;
}

public void setChannelId(String channelId) {
this.channelId = channelId;
}

public List<User> getUsers() {
return users;
}

public void setUsers(List<User> users) {
this.users = users;
}

}
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
@@ -1,26 +1,24 @@
package com.yen.springChatRoom.bean;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class OnlineUser {

public OnlineUser(){
}

public OnlineUser(List<String> users){
this.users = users;
}

private List<String> users;

public List<String> getUsers() {
return users;
}

public void setUsers(List<String> users) {
this.users = users;
}

}
//package com.yen.springChatRoom.bean;
//
//import java.util.List;
//
//public class OnlineUser {
//
// public OnlineUser(){
// }
//
// public OnlineUser(List<String> users){
// this.users = users;
// }
//
// private List<String> users;
//
// public List<String> getUsers() {
// return users;
// }
//
// public void setUsers(List<String> users) {
// this.users = users;
// }
//
//}
29 changes: 29 additions & 0 deletions springChatRoom/src/main/java/com/yen/springChatRoom/bean/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.yen.springChatRoom.bean;

public class User {

private String userName;

public User() {
}

public User(String userName) {
this.userName = userName;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,21 @@ public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("ws").withSockJS(); // if browser not support websocket, use SockJS instead
}


@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {

/**
* 配置訊息代理
*
* enableSimpleBroker: server端推送給client端的路徑prefix (server -> client)
* setApplicationDestinationPrefixes: client端發送給server端的路徑prefix (client -> server)
*
* https://hackmd.io/@mko123654/HkySHSe35
*/

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

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

import com.yen.springChatRoom.model.ChatMessage;
import com.yen.springChatRoom.bean.Channel;
import com.yen.springChatRoom.bean.ChatMessage;
import com.yen.springChatRoom.bean.User;
import com.yen.springChatRoom.service.ChatService;
import com.yen.springChatRoom.util.JsonUtil;
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;

@Controller
public class ChatController {
Expand All @@ -35,6 +36,12 @@ public class ChatController {
private RedisTemplate<String, String> redisTemplate;
//private RedisTemplate redisTemplate;

@Autowired
private ChatService chatService;

@Autowired
private SimpMessagingTemplate messagingTemplate;

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

/**
Expand Down Expand Up @@ -71,12 +78,24 @@ public void addUser(@Payload ChatMessage chatMessage, SimpMessageHeaderAccessor
headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
redisTemplate.opsForSet().add(onlineUsers, chatMessage.getSender());
redisTemplate.convertAndSend(userStatus, JsonUtil.parseObjToJson(chatMessage));

// show online user

} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}

/** user - user private msg */
@MessageMapping("/private/{channelId}")
private void handlePrivateMessage(@DestinationVariable String channelId, ChatMessage chatMessage){

Channel channel = new Channel();
if (channel != null){
for(User user : channel.getUsers()){
// TODO : check if can use redisTemplate
// TODO : check what's channel for user-user
//messagingTemplate.convertAndSendToUser(user.getUserName(), "/topic/private/" + channelId, chatMessage);
redisTemplate.convertAndSend("/topic/private/" + channelId, chatMessage);
}
}
}

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

import com.yen.springChatRoom.bean.OnlineUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -41,13 +40,11 @@ public List<String> getOnlineUser(){
Set<String> resultSet = redisTemplate.opsForSet().members(onlineUserKey);
System.out.println("(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();
return users;
}

}
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 Expand Up @@ -65,31 +65,4 @@ public void onMessage(Message message, byte[] bytes) {
}
}

// @Override
// public void onMessage(Message message, byte[] pattern) {
//
// // super.onMessage(message, pattern);
// byte[] body = message.getBody();
// byte[] channel = message.getChannel();
// String rawMsg;
// String topic;
//
// try{
// rawMsg = redisTemplate.getStringSerializer().deserialize(body);
// topic = redisTemplate.getStringSerializer().deserialize(channel);
// LOGGER.info("Receive raw msg from topic : " + topic + " , raw msg : " + rawMsg);
// }catch (Exception e){
// LOGGER.error("Receive raw msg failed : " + e.getMessage() + e);
// return; // TODO : return custom error msg instead
// }
//
// if (msgToAll.equals(topic)){
// LOGGER.info("Send msg to all users : " + rawMsg + ", topic = " + topic);
// ChatMessage chatMessage = JsonUtil.parseJsonToObj(rawMsg, ChatMessage.class);
// // send msg to all online users
// chatService.sendMsg(chatMessage);
// }else{
// LOGGER.warn("Not sending msg to all user with topic : " + topic);
// }

}
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
package com.yen.springChatRoom.service;

import com.yen.springChatRoom.bean.Channel;
import com.yen.springChatRoom.bean.User;
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;

import java.util.ArrayList;
import java.util.List;

@Service
public class ChatService {

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

private List<Channel> channels = new ArrayList<>();

public List<Channel> getAllChannels() {

return channels;
}

public Channel createChannel(String channelId, List<User> users) {

Channel channel = new Channel(channelId, users);
channels.add(channel);
return channel;
}

// TODO : implement user - user send private msg ?

@Autowired
private SimpMessageSendingOperations simpMessageSendingOperations;

Expand Down
Loading