너무 길면 보기 싫기도 하고 나도 나중에 찾기 어렵고.....해서 좀 쪼갰습니다.

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일이나 괴롭혔던

@ServerEndpoint

@Autowired
public ChatRedisRepository repo;

나옵니다. ... AutoWired를 해결하면 serverEndopoint가 안되고 serverEndopoint가 되면 autoWired가 안되는 짜증나는 상황에서 chatGPT3는 저를 악의 구렁텅이로 밀어 넣었어요....그래서 더 3일이나 걸린듯합니다.ㅠㅠ

마지막에 그냥 구글 선배님 글 검색했습니다....선배님들 최고예요!!!!!!!

이걸 해결한것이 아까 2번의

@ServerEndpoint(value="/chatting", configurator = CustomSpringConfigurator.class)

입니다. 클래스는 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도 접해봤다는것에 너무 뿌듯함을 느끼는 저만의 글입니다.^^

 

+ Recent posts