98일차

이후론 실시간 채팅 시스템 코드를 뒤죽박죽으로 기록하고 커스텀한 부분이 많아서 헷갈린다
기억나는 대로 작성해보고자 한다.

채팅나누기

관리자와의 1대1채팅방을 만들고자 했다.
여러가지 문제점이 있었다.
1.팝업창을 누르면 자꾸 방이 생성된다. -> 자바스크립트의 creatroom함수가 계속 실행되기때문임.
2.남의 채팅 목록이 보인다. -> get room에서 남의 채팅방도 보이기 때문임.
등등 이런 문제점이 있었다.

일단 관리자와의 채팅방이기 때문에 먼저 채팅방을 나누는 작업을 했다.

1. footer.js

모든 페이지에 추가하면 편하겠지만 현실적으로 그러긴 힘드니 모든 페이지에 들어있는 footer에 채팅방 아이콘을 달아 누를때마다 방이 create되게 했다.
버튼을 누르면 모달창이 켜지면서 createRoom()메소드가 실행된다.
만약 비로그인 상태라면 로그인후 이용해달라는 토스트 메시지를 띄우게 된다.
처음 누르면 채팅방목록이 뜨게 만들었엇는데 관리자와 채팅하기 버튼만 남겨놓았다.
필터링은 같은 id라면 하나만 보이게 필터링한 것이다. 후에 백엔드에서도 처리한다.
채팅하기 버튼을 누르면 goroom()함수가 실행되게 된다.
ajax요청을 통해 채팅방으로 이동하고 채팅 html자체를 돌려받게 되어 채팅을 하게 된다.

let cId = $('#cId').val();
const footerToast = document.getElementById('footerToast');
$("#fixedDiv").click(
    function() {
        if (cId === 'anonymousUser') {
            const toastBootstrap = bootstrap.Toast
                .getOrCreateInstance(footerToast);
            $(".toast-body").text("로그인 후 이용해주세요");
            toastBootstrap.show();
        } else {
            $("#chatmodal").css("display", "block");
            createRoom();
        }
    });

$(".close").click(function() {
    $("#chatmodal").css("display", "none");
    $("#customerFrame").empty();
});

function createRoom() {
    var msg = {
        roomName: cId
    };

    $.ajax({
        url: "/chat/customer",
        type: "GET",
        success: function(response) {
            $(".chatcontainer").html(response);

            commonAjax('/chat/createRoom', msg, 'post', function(result) {
                createChatingRoom(result);
            });
        },
        error: function() {
            // Ajax 요청이 실패했을 때의 처리
            window.location.href = "/";
            alert("문제가 발생했습니다. 관리자에게 문의해주세요");
        }
    });
}

function goRoom(number, name) {
    $.ajax({
        url: "/chat/moveChating",
        type: "GET",
        data: {
            roomName: name,
            roomNumber: number
        },
        success: function(response) {
            // Ajax 요청이 성공했을 때의 처리
            // response에는 서버로부터 받은 데이터가 포함된다.
            // jsp파일 링크를 리턴햇기때문에 그게 그대로 리턴된다.
            $(".chatcontainer").html(response);
        },
        error: function() {
            // Ajax 요청이 실패했을 때의 처리
            window.location.href = "/";
            alert("문제가 발생했습니다. 관리자에게 문의해주세요");
        }
    });
}

function createChatingRoom(res) {
    if (res != null) {
        var tag = "";

        var filteredRes = res.filter(function(d) {
            // 필터링 조건을 여기에 작성합니다
            return d.roomName.trim() === cId;
        });

        filteredRes
            .forEach(function(d) {
                var rn = d.roomName.trim();
                var roomNumber = d.roomNumber;

                tag += "<tr>"
                    + "<td class='go'>"
                    + "<button class='btn btn-success' type='button' onclick='goRoom(\""
                    + roomNumber
                    + "\", \""
                    + rn
                    + "\")'> <i class='fa-solid fa-comments'></i> 관리자와채팅하기</button>"
                    + "</td>" + "</tr>";
            });

        $("#roomList").empty().append(tag);
    }
}

function commonAjax(url, parameter, type, calbak, contentType) {
    $.ajax({
        url: url,
        data: parameter,
        type: type,
        contentType: contentType != null ? contentType
            : 'application/x-www-form-urlencoded; charset=UTF-8',
        success: function(res) {
            calbak(res);
        },
        error: function(err) {
            console.log('error');
            calbak(err);
        }
    });
}

2. chat컨트롤러

채팅과 관련된 컨트롤러이다.
admin과 기본이 나누어져있다.
admin은 모든 채팅방을 다보게 될것이다.
createRoom을 보면 파라미터에서 roonname을 받아오고 만약 익명이라면 null을 리턴하고 있다.
이유는 비로그인시 방이 생성되지 않도록 하기 위해서이다.

@Controller
@Slf4j
@RequestMapping("/chat/")
@RequiredArgsConstructor
public class ChatController {

    private final ChatService chatService;

    @GetMapping("list")
    public String chat() {
        return "chat/room";
    }

    @GetMapping("customer")
    public String customerChat() {
        return "chat/customer";
    }

    // 방페이지
    //@PreAuthorize("hasAuthority('admin')")
    @GetMapping("admin/list")
    public String room(Model model, Authentication authentication) {
        model.addAttribute("name", authentication.getName());
        return "admin/chat/list";
    }

    // 방 생성하기
    @PostMapping("createRoom")
    @ResponseBody
    public List<ChatRoom> createRoom(@RequestParam HashMap<Object, Object> params) {
        String roomName = (String) params.get("roomName");
        if (roomName.equals("anonymousUser")) {
            return null;
        }
        return chatService.createRoom(roomName);
    }

    // 방 정보가져오기
    @PostMapping("getRoom")
    @ResponseBody
    public List<ChatRoom> getRoom(@RequestParam HashMap<Object, Object> params) {
        return chatService.getRoom();
    }

    @GetMapping("moveChating")
    public String Chating(Model model, @RequestParam HashMap<Object, Object> params) {
        int roomNumber = Integer.parseInt((String) params.get("roomNumber"));
        List<ChatRoom> newList = chatService.getChatRoomsByRoomNumber(roomNumber);
        if (newList != null && newList.size() > 0) {
            model.addAttribute("roomName", params.get("roomName"));
            model.addAttribute("roomNumber", params.get("roomNumber"));
            return "chat/room";
        } else {
            return "/";
        }
    }

    @GetMapping("admin/moveChating")
    //@PreAuthorize("hasAuthority('admin')")
    public String adminChating(Model model, @RequestParam HashMap<Object, Object> params) {
        int roomNumber = Integer.parseInt((String) params.get("roomNumber"));
        List<ChatRoom> newList = chatService.getChatRoomsByRoomNumber(roomNumber);
        if (newList != null && newList.size() > 0) {
            model.addAttribute("roomName", params.get("roomName"));
            model.addAttribute("roomNumber", params.get("roomNumber"));
            return "admin/chat/room";
        } else {
            return "redirect:/chat/admin/list";
        }
    }

    @ResponseStatus(HttpStatus.OK)
    @PostMapping("deleteRoom")
    @ResponseBody
    public void deleteRoom(@RequestParam int roomNumber) {
        chatService.removeRoom(roomNumber);
    }
}

3. 서비스

챗서비스에서 roomList를 생성해주는데 createRoom일때 만약 방목록에 값이 있다면 바잉 존재한다고 하고 방을 생성해주지않느다.
이런식으로 중복으로 방이생성 되는 것을 막았다.

@Slf4j
@Service
public class ChatServiceImpl implements ChatService {
    private List<ChatRoom> roomList = new ArrayList<>();
    private static int roomNumber = 0;
    @Override
    public List<ChatRoom> createRoom(String roomName) {
        boolean isExistingRoom = false;
        for (ChatRoom room : roomList) {
            if (room.getRoomName().equals(roomName)) {
                isExistingRoom = true;
                break;
            }
        }
        if (!isExistingRoom) {
            ChatRoom room = new ChatRoom();
            room.setRoomNumber(++roomNumber);
            room.setRoomName(roomName);
            roomList.add(room);
        }
        return roomList;
    }

    @Override
    public List<ChatRoom> getRoom() {
        return roomList;
    }

    @Override
    public List<ChatRoom> getChatRoomsByRoomNumber(Integer roomNumber) {
        List<ChatRoom> newList = new ArrayList<>();
        for (ChatRoom room : roomList) {
            if (room.getRoomNumber() == roomNumber) {
                newList.add(room);
            }
        }
        return newList;
    }

    @Override
    public void removeRoom(int roomNumber) {
        Iterator<ChatRoom> iterator = roomList.iterator();
        while (iterator.hasNext()) {
            ChatRoom room = iterator.next();
            if (room.getRoomNumber() == roomNumber) {
                iterator.remove();
            }
        }
    }
}

2023.06.19

너무 중구난방으로 작성을 해서 순서대로 설명하기가 어렵다.
전체적으로 설명하라면 설명하겠는데 시간이 지나 작성하려니 어려움이있다.
https://github.com/ChunPingE/TeamProject2-meatshop 정확한것은 코드를 직접 참고하였으면 좋겠다.

+ Recent posts