![](https://blog.kakaocdn.net/dn/cxdIhn/btrqRUtuwDb/cukLCqdMM5kVbrMeKN6nvk/img.png)
실시간 채팅에서는 웹소켓이 필요하다
SqlSessionTemplate : 트랜잭션처리까지 스프링에서 할 수 있게 처리해 준다
root-context에 sqlSessionTemplate는 bean으로 등록되어있다 -> 스프링이 관리하는데 ioc로 인해 개발자가 아닌 스프링이하는것이다
-----------------------------------------------------------
-- 채팅방
DROP TABLE CHAT_ROOM;
CREATE TABLE CHAT_ROOM (
CHAT_ROOM_NO NUMBER PRIMARY KEY,
TITLE VARCHAR2(200) NOT NULL,
STATUS_CD NUMBER DEFAULT 1 REFERENCES STATUS ,
MEMBER_NO NUMBER REFERENCES MEMBER
);
COMMENT ON COLUMN CHAT_ROOM.CHAT_ROOM_NO IS '채팅방번호';
COMMENT ON COLUMN CHAT_ROOM.TITLE IS '채팅방제목';
COMMENT ON COLUMN CHAT_ROOM.STATUS_CD IS '채팅방상태';
COMMENT ON COLUMN CHAT_ROOM.MEMBER_NO IS '회원번호(방 개설자)';
-- 채팅 내용
CREATE TABLE CHAT_MESSAGE (
CM_NO NUMBER PRIMARY KEY,
MESSAGE VARCHAR2(4000) NOT NULL,
CREATE_DT TIMESTAMP DEFAULT SYSTIMESTAMP,
CHAT_ROOM_NO NUMBER REFERENCES CHAT_ROOM,
MEMBER_NO NUMBER REFERENCES MEMBER
);
COMMENT ON COLUMN CHAT_MESSAGE.CM_NO IS '채팅메세지번호';
COMMENT ON COLUMN CHAT_MESSAGE.MESSAGE IS '작성한 채팅 메세지';
COMMENT ON COLUMN CHAT_MESSAGE.CREATE_DT IS '메세지 작성 시간';
COMMENT ON COLUMN CHAT_MESSAGE.CHAT_ROOM_NO IS '채팅방번호';
COMMENT ON COLUMN CHAT_MESSAGE.MEMBER_NO IS '회원번호';
-- 채팅방별 참여자
CREATE TABLE CHAT_ROOM_JOIN (
MEMBER_NO NUMBER REFERENCES MEMBER,
CHAT_ROOM_NO NUMBER REFERENCES CHAT_ROOM,
PRIMARY KEY(MEMBER_NO, CHAT_ROOM_NO)
);
COMMENT ON COLUMN CHAT_ROOM_JOIN.MEMBER_NO IS '회원번호';
COMMENT ON COLUMN CHAT_ROOM_JOIN.CHAT_ROOM_NO IS '채팅방번호';
CREATE SEQUENCE SEQ_CR_NO; -- 채팅방 번호 시퀀스
CREATE SEQUENCE SEQ_CM_NO; -- 채팅 메세지 번호 시퀀스
vo객체 생성 해서 필드 선언하고
resultMap만들어야한다.
기능
목록 조회
입장
메세지
나가기
목록 조회
header.jsp에서 목록을 조회할 주소 입력
![](https://blog.kakaocdn.net/dn/Uu20S/btrqMQTuvYI/U7NdiQoWeefqOSlIK986f0/img.png)
controller
HTTP
HTTP | Websocket |
/chat/roomList | /chat/insertMessage |
/chat/으로 들어온 주소 처리를 웹소켓이 하기전 HTTP가 처리하기때문에 @RequestMapping을 진행하지 않느다
![](https://blog.kakaocdn.net/dn/CVNcN/btrqNfS3Y71/NRpQF0xtxJhA9fzvl2UFk1/img.png)
![](https://blog.kakaocdn.net/dn/di7JHJ/btrqOg41D0M/uDlO6YJjZDPOwm8JEeTuqk/img.png)
채팅방 만들기
생성된 채팅방 입장
![](https://blog.kakaocdn.net/dn/bJVGRW/btrqMQTyMRb/8Iy1hZku8bLkSInuDtQHIK/img.png)
비회원이 주소로 접근할 경우 생기는 예외는 직접 실행해 확인하고 해당 예외를 적용ㅇ하면된다
sockjs를 이용한 WebSocket 구현을 위해 라이브러리 추가
웹소켓을 위한 전용객체가 있는데 sockjs는 웹소켓과 유사한 객체를 제공하는 JS 라이브러리이다.
<c:url>
c:set = 변수선언
c:url : 값이 주소형태로 바뀌어 출력된다
Spring 웹소켓 모듈 + Jackson-databind(이미 준비된 상태)
- pom.xml에 라이브러리 추가
![](https://blog.kakaocdn.net/dn/1H9qK/btrqPiBz6lf/LAOpPrnkzues9TjkuzqWnk/img.png)
![](https://blog.kakaocdn.net/dn/cGP0AJ/btrqNzjuGlL/bKDUhnXcF88gbCqetzkd10/img.png)
동일 버전인 5.2.10버전은 오류가 있어 최신버전으로 진행
![](https://blog.kakaocdn.net/dn/bkn6k0/btrq0t29I0a/p924ddWggHgkSmELVJbSPK/img.png)
HTTP를 처리하는 방법들은
포워드
리다이렉트
에이젝스 3개를 했는데
웹소켓에서 저 3개가 아닌 bean으로 처리한다 -> DispatcherServlet
servlet-context.xml
1. namespaces 탭에서 websocket을 체크
2. Bean 생성 구문 작성
ChatWebsocketHandler
/* WebSocket
- 브라우저와 웹서버간의 전이중통신을 지원하는 프로토콜이다
- HTML5버전부터 지원하는 기능이다.
- 자바 톰캣7버전부터 지원했으나 8버전부터 본격적으로 지원한다.
- spring4부터 웹소켓을 지원한다.
(전이중 통신(Full Duplex): 두 대의 단말기가 데이터를 송수신하기 위해 동시에 각각 독립된 회선을 사용하는 통신 방식. 대표적으로 전화망, 고속 데이터 통신)
WebSocketHandler 인터페이스 : 웹소켓을 위한 메소드를 지원하는 인터페이스
-> WebSocketHandler 인터페이스를 상속받은 클래스를 이용해 웹소켓 기능을 구현
WebSocketHandler 주요 메소드
void handlerMessage(WebSocketSession session, WebSocketMessage message)
- 클라이언트로부터 메세지가 도착하면 실행
void afterConnectionEstablished(WebSocketSession session)
- 클라이언트와 연결이 완료되고, 통신할 준비가 되면 실행
void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus)
- 클라이언트와 연결이 종료되면 실행
void handleTransportError(WebSocketSession session, Throwable exception)
- 메세지 전송중 에러가 발생하면 실행
----------------------------------------------------------------------------
TextWebSocketHandler : WebSocketHandler 인터페이스를 상속받아 구현한 텍스트 메세지 전용 웹소켓 핸들러 클래스
handlerTextMessage(WebSocketSession session, TextMessage message)
- 클라이언트로부터 텍스트 메세지를 받았을때 실행
웹소켓 통신 : 응답이 없어도 요청이 된다
*/
![](https://blog.kakaocdn.net/dn/EgN2z/btrqOgEAium/OMEePdWeyrqQFj1CGo4UXK/img.png)
![](https://blog.kakaocdn.net/dn/cnGS3K/btrq0Yu4AWy/2kBQKoHWNWXxfSAeVAq3g0/img.png)
package edu.kh.fin.chat.websocket;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
// 웹소켓 관련 요청/응답 코드를 작성하는 클래스(bean으로 등록되었다)
// TextWebSocketHandler : websocketHandler 자식
public class ChatWebsocketHandler extends TextWebSocketHandler{
// 클라이언트와 연결이 완료되고, 통신할 준비가 되면 실행
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// TODO Auto-generated method stub
super.afterConnectionEstablished(session);
}
// 클라이언트로부터 웹소켓통신으로 텍스트 메세지를 전달 받은 경우
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// TODO Auto-generated method stub
super.handleTextMessage(session, message);
}
// 클라이언트와 연결이 종료되면 실행
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// TODO Auto-generated method stub
super.afterConnectionClosed(session, status);
}
}
chat.js
서로 다른 두 명이 같은 통신을 사용하고 있다는 것
왼 : 보낸메세지를 받음
오 : 메세지를 보냄
![](https://blog.kakaocdn.net/dn/5JHU4/btrqOfZ2kJh/cSX4wHVyBxkJgUUt581gP0/img.png)
![](https://blog.kakaocdn.net/dn/cbjwoi/btrqY9cX1eV/JvRQz2yYWhJM4N2GKpjpV0/img.png)
java에서 json 객체형식을 만들기 위해서는 json object로 만들어 값을 하나씩 얻어와
새로운 ChatMessage 객체를 생성해서 값을 set했었다
jackson-databind