티스토리 뷰

앞의 게시글에서는 websocket 사용 환경을 설정하고 stomp를 이용한 기본적인 구현을 해보았다. 

 

[spring 멀티 채팅] websocket,sockjs,STOMP 이용한 채팅 기능-설정(1)

[spring 멀티 채팅] websocket,sockjs,STOMP 이용한 채팅 기능-STOMP채팅구현(2)

 

채팅방에 접속해서 사람들과 실시간 메시지 보내기, 받기 기능이 가능한 것 까지가 기본적인 구현이고, 채팅방으로서의 기능을 하려면 내가 채팅방에 접속하기 이전에 내용들도 당연히 볼 수 있어야 한다.

 

카카오톡 같은 채팅앱에서 위로 스크롤 시 이전 메시지를 불러오는데 이 기능이 바로 무한 스크롤(스크롤 페이징)이다.

 

기본 레이아웃 구성

 

채팅 div class = ". chatcontent"

.chatcontent { 
height: 700px; 
width : 100%; 
overflow-y: scroll; 
}

 

채팅 메시지 창 div id="list-chat"

각 채팅은 <li data-no='db에서 가져온 chatting id'> 채팅 내용 </li>

 

 

기능 구현

* 전역 변수 사용

isScrolled : 업 스크롤 이벤트로 채팅 리스트가 가져와서 뿌려지는 중에 다시 스크롤 이벤트가 일어나지 않게 하기 위함

isEnd : db에 저장되어 있는 채팅 리스트를 처음까지 다 가져왔을 경우 체크


 

 

1. 업 스크롤 이벤트를 감지한다.

//무한 스크롤
	$(".chatcontent").scroll(function() {
		var $window = $(this);
		var scrollTop = $window.scrollTop();

		// scrollbar의 위치가 위의1px까지 도달 &&
        // 스크롤 이벤트로 fetchList()가 불려서 채팅 리스트를 가져오는 중이 아니라면
        // fetchList()를 통해 채팅 리스트를 가져옴
		if (scrollTop < 1 && isScrolled == false) {
			isScrolled = true;
			fetchList();

		}
	})

 

 

 

 

 

2. 제일 상단까지 올릴 경우 해당 채팅의 data-no값 가져온다.

3. data-no가 데이터베이스 chatting 테이블의 id 값 이므로 id값 이전 10개 채팅 데이터 가져온다.

var fetchList = function() {
		
        //이미 처음 데이터까지 가져온 경우라면 더이상 db접근이 필요 없음.
		if (isEnd == true) {
			return;
		}

		// 채팅 리스트를 가져올 때 시작 번호
		// 가장 상단 채팅의 data-no값을 가져옴 
		var endNo = $("#list-chat li").first().data("no") || 0;
		
        //컨트롤러단에 채팅 리스트 요구함
		$.ajax({
			url : "${pageContext.request.contextPath}/chat/chatList.do?endNo="
					+ endNo + "&roomNo=${roomNo}",
			type : "GET",
			dataType : "json",
			success : function(result) {

				// 컨트롤러에서 가져온 방명록 리스트는 result.data에 담김
				var length = result.size;
                
                //가져온게 10개 미만이면 처음까지 가져온것
				if (length < 10) {
					isEnd = true;
				}
                //가져온 데이터마다 채팅 리스트로 만들기
                //vo에 chat객체 한개가 담김
				$.each(result, function(index, vo) {
					var html = renderList(vo,0);
					$("#list-chat").prepend(html);

				})
//여기 아래부분부터 renderList()로 채팅 리스트 생성 후 처리과정 - 5번

 

 

 

 

 

4. 채팅 html 만들어서 채팅 칸에 뿌려준다.

var renderList = function(vo,endNo) {
	
		// 리스트 html을 정의
		var date = moment(vo.sendDate).format('YY/MM/DD HH:mm');
		var html = "";
		if(endNo==0) endNo = vo.no;
		
		//내가 보낸 채팅일 경우
		if(vo.memberId=="${loginMember.memberId}"){
			//신고된 채팅일 경우
			var content ="";
			if(vo.vaildYN == 'Y'){
				content = "<p class='myChat text-muted p-2'><b>신고된 채팅입니다.</b></p>";
			}
			if(vo.vaildYN != 'Y'){
				content = "<p class='myChat text-left p-2'>"+vo.chatContent+"</p>";
			}
		
		html = 	"<li class='me pr-2' data-no='"+ endNo +"'>"
				+ "<strong>" + vo.memberId + "</strong>"
				+"<div class='me'>"
				+ "<strong style='display : inline;' class='align-self-end'>" + date + "</strong>"
				+ content
				+"</div>"
				+ "</li>";
		

		}
		//남이 보낸 채팅일 경우
		else{
			//신고된 채팅일 경우
			var content ="";
			var report ="";
			if(vo.vaildYN == 'Y'){
				content = "<p class='otherChat bg-light text-muted p-2'><b>신고된 채팅입니다.</b></p>";
			}
			if(vo.vaildYN != 'Y'){
				content = "<p class='otherChat bg-light p-2'>"+vo.chatContent+"</p>";
				report = "신고";
			}
			html = "<li class='pl-2' data-no='"+ vo.no +"'>"
				+ "<strong>" + vo.memberId + "</strong>"
				+"<div class='row ml-0'>"
				+ content
				+ "<strong class='align-self-center'>" + date + "<a href='#' class='reportModalK'>"+report+"</a></strong>"
				+"</div>"
				+ "</li>";
		
		}
		return html;
			
		

	}

 

 

 

 

5. 스크롤은 읽은 곳까지. 즉, 새로 채팅 가져오기 바로 전의 제일 위에 위치해야 한다.

    이를 위해 2번에서 data-no를 저장하고, 이 위치로 스크롤을 이동시킨다.

// 2,3번 fetchList() 아래부분으로 renderList()처리되고 난 후
				
                //아까 채팅 리스트 db에서 가져오기 전에 저장해놓은 data-no(읽은 최상단)
        		//스크롤 위치를 정함
				var position = $('[data-no='+endNo+']').prev().offset();//위치값
				//해당 위치로 스크롤 이동
				document.querySelector('.chatcontent').scrollTo({top : position.top,behavior : 'auto'});
				//스크롤중 변수를 false로 돌려놔줌 -> 다시 업스크롤 일어나면 채팅리스트 가져올 수 있게
                isScrolled = false;
			},
			error : function(xhr, status, err) {
				console.log("처리실패!");
				console.log(xhr);
				console.log(status);
				console.log(err);
			}
		});
	}

 

동작 화면

+ 개인적으로 새로운 채팅을 가져온 후에 읽었던 곳까지 스크롤을 이동시키는 부분과, 채팅 html을 만들 때 상대방 채팅, 내채팅, 내 프로젝트에서는 신고된 채팅인지 확인해서 ui를 맞춰줘야 하는 부분이 까다로웠다 ㅠ

 

+ 스크롤바가 생성되어야 하기 때문에 어느 정도 채팅 데이터가 있어야 가능하다. 또한 처음 채팅방에 입장했을 때에는 20개 정도 기본 채팅 리스트를 가져와야 한다!

 

+ 나의 프로젝트에 맞춘 채팅창이기 때문에 뭔가 잘 안 되는 부분이 있다거나 잘못된 부분이 있을 수 있다!

 

+ 검색으로 어떤 분의 블로그를 참고하여 개발하였는데 못 찾음... 혹시 이 글을 보신 분들(있으려나,,) 중 댓글로 달아주신다면 참고사이트로 추가하겠습니다!

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함