본문 바로가기

개발/BACK

[SpringFramework] WebSocket통신을 이용한 간단한 쪽지(메세지) 기능 구현 예제[1]

728x90

이번에는 저번에 Socket을 구현하여 1대1 및 다중 채팅 기능을 구현했다면, 

이번에는 웹소켓을 이용해 다른 이에게 쪽지를 보내고, 확인할 수 있는 기능을 구현할 예정이다.

 

웹소캣은 http 프로토콜을 이용한 단방향 통신이 아닌 양방향 통신 기술이다. http 보다 통신 시,

헤더가 더 작기 때문에, 실시간 통신에 적합한 기술이다.

 

다음포스팅

https://hdhdeveloper.tistory.com/39

 

[SpringFramework] WebSocket 통신을 이용한 간단한 쪽지(메세지) 기능 구현[2]

지난 포스팅에서는 웹 소켓을 통해 쪽지를 발송했으면, 해당 쪽지의 건수를 상단 메인 화면에 뿌려주는 작업까지 진행했다 지난 포스팅 링크 https://hdhdeveloper.tistory.com/38 [SpringFramework] WebSocket통..

hdhdeveloper.tistory.com


 

먼저 쪽지 기능을 구현하기 위해 TB_MESSAGE 라는 테이블을 구현했다.

예제로 구현하기 위해서 대충 만든 테이블이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE `tb_message` (
`ms_title` VARCHAR(50NULL DEFAULT NULL,
`receiver_name` VARCHAR(50NULL DEFAULT NULL,
`gubun` INT(1NULL DEFAULT '0',
`creat_dt` DATE NULL DEFAULT NULL,
`ms_content` VARCHAR(500NULL DEFAULT NULL,
`sender_name` VARCHAR(50NULL DEFAULT NULL,
`user_id` VARCHAR(50NOT NULL,
`read_yn` INT(1NOT NULL DEFAULT '0',
PRIMARY KEY (`user_id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
cs

 

데이터베이스는 [MYSQL]로 동일하게 구성을 해준다

gubun 컬럼의 경우, 수신과 발신을 한 테이블에 넣기 때문에, 구분해줄 필요가 있어서 생성했다

 

user_id는 발송자의 id값이다

read_yn 컬럼은 쪽지를 읽었는지에 대한 유무값이다

 

 

그 후, 채팅 기능을 구현할 때와 마찬가지로, pom.xml에 dependency를 추가해준다

 

1
2
3
4
5
6
7
8
9
10
11
12
<!-- web socket -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.1</version>
            <scope>provided</scope>
        </dependency>
cs

 

 

그리고 EchoHandler , WebSocketConfig ,servlet-context.xml 을 다음과 같이 설정해준다

 

해당 설정은 채팅 구현때와 동일하게 하며,

링크를 아래에 참조하니 아래 링크를 보면서 설정해주면 될 것 같다.

hdhdeveloper.tistory.com/30

 

[SpringFramework] Socket을 통한 스프링 채팅 기능 구현

스프링 환경에서 채팅 기능을 구현할 수 있다. TCP/IP 프로토콜을 사용하여 서버와 통신하는 클라이언트 프로그램을 구현할 수 있는 Socket 통신을 이용할 것이다. 채팅을 구현하기 위해서는 Socket

hdhdeveloper.tistory.com

해당 링크 처럼 설정을 끝마쳤다면, EchoHandler.java를 열어서

afterConnectionEstablished 메소드를 다음과 같이 수정하자

 

1
2
3
4
5
6
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String user_name = searchUserName(session);
        sessionList.add(session);
            session.sendMessage(new TextMessage("recMs :"+messageMapper.countMessageView(user_name)));
    }
cs

user_name 값을 가져와서 messageMapper 의 countMessageView 메소드를 호출한다

 

해당 메소드는 파라미터 (사용자 이름)로 데이터베이스에 입력되어있는 값을 모두 호출하는 메소드다

소스는 이렇다

 

MessageMapper.java 

1
2
3
4
5
6
7
8
9
10
11
package main.com.basic.dao;
 
import org.apache.ibatis.annotations.Mapper;
 
 
@Mapper
public interface MessageMapper {
 
    public String countMessageView(String user_id);
}
 
cs

 

 

경로는 다음과 같다. 하단에 mappers 폴더에 MessageMapper도 생성해주자

 

MessageMapper.xml

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="main.com.basic.dao.MessageMapper">
    <select id="countMessageView" resultType="String">
        select count(*from tb_message where receiver_name= #{receiver_name} and gubun = 0
    </select>
        
</mapper>
cs

 

구분 값이 0인 것은 발송한 메세지가 아닌 발송 된 메세지를 카운트해서 가져와야 하기 때문에 gubun 값은 0으로 준다.

(발송은 1)

 


 

다음은 JSP 페이지를 보자

먼저 로그인을 했을 때, 로그인 옆에 메세지를 띄워줄 것이기 때문에,

Handler에서 호출해온 값을 span태그에 붙일 것이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div class="container-header">
        <input type="hidden" value="<c:out value='${sessionConfigVO.user_id }'/>" id="session_id"/>
            <c:if test="${sessionConfigVO ne null}">
                <ul style="height:30px;float:right;margin-bottom:20px;" class="fn-font">
                    <li><a style="color:blue;" class="" >${sessionConfigVO.user_name}' s come in</a></li>
                    <c:if test="${sessionConfigVO.naver_login eq true }">
                        <li>
                            <img src="../resources/images/naver_logo.png" style="width:30px;">
                            <a style="color:green;">NAVER 계정으로 접속중 </a>
                            <span id="count" class="badge bg-theme"></span>
                        </li>
                    </c:if>
                </ul>
            </c:if>
            <c:if test='${sessionConfigVO eq null}'>
                <ul style="height:30px;float:right;margin-bottom:20px;" class="fn-font">
                    <li><a style="color:blue;" class="forget_login" onclick="fn_forgetID()">Forget ID/PASSWORD</a></li>
                </ul>    
            </c:if>
            <span id="recMs" name="recMs" style="float:right;cursor:pointer;margin-right:10px;color:pink;"><img src="../resources/images/msgicon.png" style="width:15px;"></span>
        </div>
cs

하단에 id값이 recMs 인 span태그에 내가 MessageMapper에서 쿼리를 돌려 가져온 값을 넣어줄 것이다.

그리고 해당 msgicon.png 파일은 아래에 따로 첨부해놓겠다.

msgicon.png
0.00MB

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<script type="text/javascript">
var socket = null;
var sock = new SockJS("/echo");
socket =sock;
$(document).ready(function(){
    if(!isEmpty($("#session_id").val()))
            connectWS();
});
    $(".chat_start_main").click(function(){
        $(this).css("display","none");
        $(".chat_main").css("display","inline");
    })
    $(".chat_main .modal-header").click(function(){
        $(".chat_start_main").css("display","inline");
        $(".chat_main").css("display","none");
    });
 
    function connectWS(){
        sock.onopen = function() {
               console.log('info: connection opened.');
        };
        sock.onmessage = function(e){
            var splitdata =e.data.split(":");
            if(splitdata[0].indexOf("recMs"> -1)
                $("#recMs").append("["+splitdata[1]+"통의 쪽지가 왔습니다.]");
            else
                $("#chat").append(e.data + "<br/>");
        }
        sock.onclose = function(){
            $("#chat").append("연결 종료");
//              setTimeout(function(){conntectWs();} , 10000); 
        }
        sock.onerror = function (err) {console.log('Errors : ' , err);};
 
    }
    
    $("#board1").click(function(){
        location.href="/board/main_board.do";
    });
 
$("#chatForm").submit(function(event){
        event.preventDefault();
            sock.send($("#message").val());
            $("#message").val('').focus();    
    });    
</script>
cs

  sock.onmessage = function(e) 부분을 보면 e.data의 값이 EchoHandler에서 가져온 값이라고 볼 수 있다.

  지금 해당 값을 파싱하는 이유는 채팅 기능을 구현할 때와 동일한 Handler를 사용해버려서, 

  요청 시에 , 쪽지의 갯수를 호출해서 값을 날려준다.


아까 수정했던 EchoHandler 값의 데이터를 이런 식으로 TextMessage에 담기 때문에

  session.sendMessage(new TextMessage("recMs :"+messageMapper.countMessageView(user_name)));

recMs의 값이 있는지 체크하기 위해 데이터 파싱을 한 것이다.

결과물 : 

728x90