너무 길면 보기 싫기도 하고 나도 나중에 찾기 어렵고.....해서 좀 쪼갰습니다.
3. controller는 2가지로 볼수가 3가지로 볼수가 있습니다. 처음 화면 이동은 HomeContrller가 이건 뭐 비슷들 하니깐...pass
그다음 채팅방 입장을 위해서와 여러가지 로직들을 처리하는 ChatContrller와 채팅의 websocket을 위한 controller 로 볼수 있습니다.
이 websocket은
@Component
@ServerEndpoint(value="/chatting", configurator = CustomSpringConfigurator.class)
public class WebSocketChatt {
@Autowired
public ChatRedisRepository repo;
private static Set<Session> clients = Collections.synchronizedSet(new HashSet<Session>());
public WebSocketChatt() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
@OnMessage
public void onMessage(Session session, String message) throws Exception {
// 메시지 처리 로직 작성
System.out.println("receive WebSocketChatt message : " + message);
// ChatDto 객체 생성
ObjectMapper objectMapper = new ObjectMapper();
ChatDto chatDto = objectMapper.readValue(message, ChatDto.class);
// ChatDto 객체를 Redis에 저장
try {
repo.save(chatDto);
} catch (Exception e) {
e.printStackTrace();
System.out.println("에러 : " + e.getMessage());
}
for (Session s : clients) {
System.out.println("send data : " + message);
s.getBasicRemote().sendText(message);
}
}
//클라이언트가 접속할때
@OnOpen
public void onOpen(Session session) {
System.out.println("open session : " + session.toString());
if(!clients.contains(session)) {
clients.add(session);
System.out.println("session open : " + session);
}else {
System.out.println("이미 연결된 session 임!!!");
}
}
@OnClose //클라이언트 종료시,,,브라우저 끄러나 다른 경로 갈때.
public void onClose(Session session) {
System.out.println("session close : " + session);
repo.findChatList();
clients.remove(session);
}
}
여기서 저를 3일이나 괴롭혔던
@Autowired
public ChatRedisRepository repo;
나옵니다. ... AutoWired를 해결하면 serverEndopoint가 안되고 serverEndopoint가 되면 autoWired가 안되는 짜증나는 상황에서 chatGPT3는 저를 악의 구렁텅이로 밀어 넣었어요....그래서 더 3일이나 걸린듯합니다.ㅠㅠ
마지막에 그냥 구글 선배님 글 검색했습니다....선배님들 최고예요!!!!!!!
이걸 해결한것이 아까 2번의
입니다. 클래스는 2번 스토리에 있어요...^^ springboot, webSocket, Redis. chat --2. 설정 및 DTO :: 미치게힘든코딩 (tistory.com)at --2. 설정 및 DTO ::
springboot, webSocket, Redis. chat --2. 설정 및 DTO
1. 웹소켓을 통해 채팅 프로그램 만들기...1에서 왠만한건 다 복붙해서 이런건 감사... 2. 1:N 으로 적용해야합니다. 3. 저장은 DB로 해야하는데 이때 저는 REDIS를 알게 되었습니다. 그냥 활용해보기..
codingisnoteasy.tistory.com
추가는 DTO객체를 적용시킨것 밖에는 없어요....1번글의 선배님 글에서 ....
@Repository
public class ChatRedisRepository {
private static final Logger logger = LoggerFactory.getLogger(ChatRedisRepository.class);
private static final String HASH_KEY = "chatData";
private RedisTemplate<String, ChatDto> RedisTemplate;
private HashOperations<String, String, Map<String, String> > hashOperations;
public ChatRedisRepository(RedisTemplate<String, ChatDto> RedisTemplate) {
this.RedisTemplate = RedisTemplate;
this.hashOperations = RedisTemplate.opsForHash();
}
public void save(ChatDto chatDto) {
String key = chatDto.getId(); //자동생성된 id 값을 사용한다.
Map<String, String> hashData = new HashMap<>();
hashData.put("nickName", chatDto.getNickName());
hashData.put("message", chatDto.getMessage());
hashData.put("roomName", chatDto.getRoomName());
hashData.put("date", chatDto.getDate());
hashOperations.put(HASH_KEY, key, hashData);
}
public ChatDto findByNickName(String nickName) {
Map<String, String> hashData = hashOperations.get(HASH_KEY, nickName);
logger.info("******** findByNickName hashData : {}", hashData);
if (!hashData.equals("null") || hashData != null) {
ChatDto cDto = ChatDto.builder().roomName(nickName).build();
return cDto;
}
return null;
}
//모든 대화 리스트 출력
public void findChatList() {
Map<String, Map<String, String> > allEntries = hashOperations.entries(HASH_KEY);
logger.info("채팅 전체 데이터 : ");
logger.info("{}",allEntries);
logger.info("-----------------------");
for (Map.Entry<String, Map<String, String>> entry : allEntries.entrySet()) {
String key = entry.getKey();
Map<String, String> data = entry.getValue();
System.out.println("Key: " + key);
ChatDto chat = new ChatDto();
chat.setNickName(data.get("nickName"));
System.out.print("nickName : "+ chat.getNickName());
chat.setMessage(data.get("message"));
System.out.print(", message : "+ chat.getMessage());
chat.setRoomName(data.get("roomName"));
System.out.print(", roomName : "+ chat.getRoomName());
chat.setDate(data.get("date"));
System.out.println(", date : "+ chat.getDate());
System.out.println("---------------------");
}
}
전체 조회하면 이런식으로 나옵니다. 이걸 활용해서 이것저것 할수 있는거죠..^^
추가로 채팅정보에 관련된 controller는
@Controller
public class ChatController {
private static final Logger logger = LoggerFactory.getLogger(ChatController.class);
private ChatRedisRepository repo;
private RoomRedisRepository roomRepo;
@Autowired
public ChatController(ChatRedisRepository repo,RoomRedisRepository roomRepo ) {
this.repo = repo;
this.roomRepo = roomRepo;
}
@Autowired
private RedisTemplate<String, CRoomDto> redisTemplate;
@RequestMapping("/chatting")
public ModelAndView searchRoomNum(String roomName, String password, ModelAndView mv) throws JsonProcessingException {
try{
CRoomDto cRoo = roomRepo.findById(roomName);
if (cRoo.getPassWord() == null ) {
CRoomDto cRoom = CRoomDto.builder().roomName(roomName).passWord(password).build();
roomRepo.save(cRoom);
mv.addObject("roomName", roomName);
mv.setViewName("chat/chatting");
return mv;
} else {
mv.addObject("roomName", roomName);
mv.setViewName("chat/chatting");
logger.info("all list : {}",roomRepo.findRoomAll());
return mv;
}
}catch (JsonProcessingException je){
mv.addObject("message", je.getMessage());
mv.setViewName("index");
return mv;
}
}
}
이런거였습니다.......
제가 국비학원 졸업시 프로젝트 부분이 ajax으로 하는 채팅프로그램였습니다. 그때는 부트를 배우기 전이라서 나중에 꼭 부트 공부하고 websocket으로 해보리라 다짐했는데 업무로 어거지로 한것이 아니라 제스스로 했다는 만족감과
제가 redis도 접해봤다는것에 너무 뿌듯함을 느끼는 저만의 글입니다.^^
'SPRING' 카테고리의 다른 글
mySql 설치....재설치...오류들 (0) | 2023.09.21 |
---|---|
springboot, webSocket, Redis. chat --2. 설정 및 DTO (0) | 2023.06.09 |
springboot, webSocket, Redis. chat --1 설치 (1) | 2023.06.09 |
구글 translation api 사용해보기. (1) | 2023.05.20 |
이클립스 부트 mariaDB설치 ...에러백만돌이 (0) | 2023.05.19 |