2018 - 01 - 23 (화)
웹 소켓
프로젝트에 웹소켓을 활용하여 쪽지, 채팅 기능을 구현할 필요성이 생기게되어 웹 소켓에대해서 공부해 보았다.
사실 학교다닐 적에 통신관련 수업시간에 소켓에 대해서 수업을 들은적이 있다. 기억하기로는 OSI 5계층 중 4계층인 전송계층(Transport layer) 와 5계층인 응용계층 (Application layer) 사이에 존재하여 전송계층에 의존하고 이 두계층 사이에서 게이트? 역활을 한다. 라고 기억하고 있습니다.
결국 .. COMPUTER NETWORKING A TOP-DOWN Approach 라는 (전공서적) 을 펼쳐서 소켓부분을 찾게되었다. 해당 책에서는 UDP / TCP 소켓 프로그래밍을 소개하는데 이를 파이썬으로 소개한다.
프로젝트에 TCP 소켓 프로그래밍을 해야하는 나는 TCP 부분을 중점적으로 보았다.
TCP는 UDP 와 달리 손실? 을 싫어한다.(데이터의 정확하고 안정적인 전달이 핵심) 기본적으로 TCP 는 3Way handshaking 을 통해 연결지향적인 통신을 한다. 이 때 클라이언트 소켓 (IP 주소 및 포트번호) 와 서버 소켓 (IP주소 및 포트번호) 에 연결을 시도한다.
1 . 클라이언트가 TCP 연결을 위해 서버로 요청 메시지를 보낸다. 이 메시지는 소켓을 거쳐 서버에 전달된다.
2 . 서버는 반대로 클라이언트 주소로 응답 메시지를 보내고 이는 출입문이라고 할 수 있는 소켓을 통해 전달된다.
3 . 승인하는 응답을 보낼 경우 핸드셰이킹이 이루어진다. 소켓을 연결하는 파이프를 통해 바이트를 송수신 할 수 있게 된다.
웹소켓은 TCP 접속에 양방향 통신 채널하는 프로토콜이며 웹소켓의 API 는 W3C 에의해 표준화 되어있다.
DB설계
1 .. 두개의 테이블을 생성해주었다. CHATROOM 테이블과 MESSAGE 테이블
실습
1 .. https://github.com/sockjs/sockjs-client 에서 dist 의 sockjs.js 를 내려받아 프로젝트의 resource/js 폴더에 추가한다.
2 .. pom.xml 에 라이브러리 추가 (프로젝트의 스프링 버전은 4.1.7이다.)
<!-- https://mvnrepository.com/artifact/org.springframework/spring-websocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.9</version>
</dependency>
<!-- jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.4</version>
</dependency>
3 .. ws-config.xml 생성 (웹소켓 관련 xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="chatHandler" class="com.almom.handler.ChatWebSocketHandler" />
<websocket:handlers>
<websocket:mapping handler="chatHandler" path="/chat" />
<websocket:handshake-interceptors>
<bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor" />
</websocket:handshake-interceptors>
<websocket:sockjs />
</websocket:handlers>
<mvc:default-servlet-handler />
</beans>
4 .. jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<html>
<head>
<link rel="stylesheet" type="text/css"
href="../../../resources/css/bootstrap-grid.css">
<link rel="stylesheet" type="text/css"
href="../../../resources/css/bootstrap-reboot.css">
<link rel="stylesheet" type="text/css"
href="../../../resources/css/bootstrap.css">
<link rel="stylesheet" type="text/css"
href="../../../resources/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css"
href="../../../resources/css/page.css">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css"
href="../../../resources/css/style.css">
<script type="text/javascript"
src="../../../resources/js/jquery-3.2.1.js"></script>
<script type="text/javascript"
src="../../../resources/js/sockjs.min.js"></script>
<style>
</style>
</head>
<body>
<c:set var="profile" value='<%=session.getAttribute("login")%>' />
<div class="col-12 row justify-content-center align-items-center my-5 ">
<a href=""><img src="../../../resources/image/AlmomLogo.png"
alt="Almom Logo" width="180px" class="img-fluid" /></a>
</div>
<div class="col-12">
<div class="col-2" style="float: left">
<span> 목록 </span>
</div>
<div class="col-8" style="float: left; text-align: center;">
${tutor_name } 님과 대화</div>
<div class="col-2" style="float: right">
<span> 닫기 </span>
</div>
</div>
<div class="col-12" style="margin-top: 40px; clear: both;">
<div class="col-10"
style="margin: 20px auto; text-align: center; color: white; background-color: #01D1FE; border: 1px solid #01D1FE; padding: 10px 10px; border-radius: 8px;">
수업 일정과 강의 내용에 대해 문의해보세요. <br>(연락처 문의 또는 직접 알려주는 것은 불가)
</div>
</div>
<!-- 채팅 내용 -->
<div class="col-12">
<div class="col-11"
style="margin: 0 auto; border: 1px solid #01D1FE; height: 400px; border-radius: 10px; overflow:scroll" id = "chatArea">
<div id="chatMessageArea" style = "margin-top : 10px; margin-left:10px;"></div>
</div>
</div>
<!-- 채팅 입력창 -->
<div class="col-12" style="margin-top: 20px; margin-bottom: 15px;">
<div class="col-12" style="float: left">
<textarea class="form-control"
style="border: 1px solid #01D1FE; height: 65px; float: left; width: 80%"
placeholder="Enter ..." id = "message">
</textarea>
<span
style="float: right; width: 18%; height: 65px; text-align: center; background-color: #01D1FE; border-radius: 5px;">
<a
style="margin-top: 30px; text-align: center; color: white; font-weight: bold;" id = "sendBtn"><br>전송</a>
</span>
</div>
</div>
<img id="profileImg" class="img-fluid"
src="/displayFile?fileName=${userImage}&directory=profile" style = "display:none">
<input type="text" id="nickname" value = "${user_name }" style = "display:none">
<input type="button" id="enterBtn" value="입장" style = "display:none">
<input type="button" id="exitBtn" value="나가기" style = "display:none">
<script type="text/javascript">
connect();
function connect() {
sock = new SockJS('/chat');
sock.onopen = function() {
console.log('open');
};
sock.onmessage = function(evt) {
var data = evt.data;
console.log(data)
var obj = JSON.parse(data)
console.log(obj)
appendMessage(obj.message_content);
};
sock.onclose = function() {
appendMessage("연결을 끊었습니다.");
console.log('close');
};
}
function send() {
var msg = $("#message").val();
if(msg != ""){
message = {};
message.message_content = $("#message").val()
message.TUTOR_USER_user_id = '${TUTOR_USER_user_id}'
message.USER_user_id = '${profile.user_id}'
message.CLASS_class_id = '${class_id}'
message.message_sender = '${profile.user_id}'
}
sock.send(JSON.stringify(message));
$("#message").val("");
}
function getTimeStamp() {
var d = new Date();
var s =
leadingZeros(d.getFullYear(), 4) + '-' +
leadingZeros(d.getMonth() + 1, 2) + '-' +
leadingZeros(d.getDate(), 2) + ' ' +
leadingZeros(d.getHours(), 2) + ':' +
leadingZeros(d.getMinutes(), 2) + ':' +
leadingZeros(d.getSeconds(), 2);
return s;
}
function leadingZeros(n, digits) {
var zero = '';
n = n.toString();
if (n.length < digits) {
for (i = 0; i < digits - n.length; i++)
zero += '0';
}
return zero + n;
}
function appendMessage(msg) {
if(msg == ''){
return false;
}else{
var t = getTimeStamp();
$("#chatMessageArea").append("<div class='col-12 row' style = 'height : auto; margin-top : 5px;'><div class='col-2' style = 'float:left; padding-right:0px; padding-left : 0px;'><img id='profileImg' class='img-fluid' src='/displayFile?fileName=${userImage}&directory=profile' style = 'width:50px; height:50px; '><div style='font-size:9px; clear:both;'>${user_name}</div></div><div class = 'col-10' style = 'overflow : y ; margin-top : 7px; float:right;'><div class = 'col-12' style = ' background-color:#ACF3FF; padding : 10px 5px; float:left; border-radius:10px;'><span style = 'font-size : 12px;'>"+msg+"</span></div><div col-12 style = 'font-size:9px; text-align:right; float:right;'><span style ='float:right; font-size:9px; text-align:right;' >"+t+"</span></div></div></div>")
var chatAreaHeight = $("#chatArea").height();
var maxScroll = $("#chatMessageArea").height() - chatAreaHeight;
$("#chatArea").scrollTop(maxScroll);
}
}
$(document).ready(function() {
$('#message').keypress(function(event){
var keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '13'){
send();
}
event.stopPropagation();
});
$('#sendBtn').click(function() { send(); });/*
$('#enterBtn').click(function() { connect(); });
$('#exitBtn').click(function() { disconnect(); }); */
});
</script>
</body>
</html>
- handler
package com.almom.handler;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Inject;
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;
import com.almom.domain.ChatRoomVO;
import com.almom.domain.MessageVO;
import com.almom.domain.UserVO;
import com.almom.persistence.ChatDAO;
import com.google.gson.Gson;
public class ChatWebSocketHandler extends TextWebSocketHandler {
@Inject
private ChatDAO dao;
private List<WebSocketSession> connectedUsers;
public ChatWebSocketHandler() {
connectedUsers = new ArrayList<WebSocketSession>();
}
private Map<String, WebSocketSession> users = new ConcurrentHashMap<String, WebSocketSession>();
@Override
public void afterConnectionEstablished(
WebSocketSession session) throws Exception {
log(session.getId() + " 연결 됨!!");
users.put(session.getId(), session);
connectedUsers.add(session);
}
@Override
public void afterConnectionClosed(
WebSocketSession session, CloseStatus status) throws Exception {
log(session.getId() + " 연결 종료됨");
connectedUsers.remove(session);
users.remove(session.getId());
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
System.out.println(message.getPayload());
Map<String, Object> map = null;
MessageVO messageVO = MessageVO.convertMessage(message.getPayload());
System.out.println("1 : " + messageVO.toString());
ChatRoomVO roomVO = new ChatRoomVO();
roomVO.setCLASS_class_id(messageVO.getCLASS_class_id()); //클래스
roomVO.setTUTOR_USER_user_id(messageVO.getTUTOR_USER_user_id()); //튜터
roomVO.setUSER_user_id(messageVO.getUSER_user_id()); //유저
ChatRoomVO croom =null;
if(!messageVO.getUSER_user_id().equals(messageVO.getTUTOR_USER_user_id())) {
System.out.println("a");
if(dao.isRoom(roomVO) == null ) {
System.out.println("b");
dao.createRoom(roomVO);
System.out.println("d");
croom = dao.isRoom(roomVO);
}else {
System.out.println("C");
croom = dao.isRoom(roomVO);
}
}else {
croom = dao.isRoom(roomVO);
}
messageVO.setCHATROOM_chatroom_id(croom.getChatroom_id());
if(croom.getUSER_user_id().equals(messageVO.getMessage_sender())) {
messageVO.setMessage_receiver(roomVO.getTUTOR_USER_user_id());
}else {
messageVO.setMessage_receiver(roomVO.getUSER_user_id());
}
for (WebSocketSession websocketSession : connectedUsers) {
map = websocketSession.getAttributes();
UserVO login = (UserVO) map.get("login");
//받는사람
if (login.getUser_id().equals(messageVO.getMessage_sender())) {
Gson gson = new Gson();
String msgJson = gson.toJson(messageVO);
websocketSession.sendMessage(new TextMessage(msgJson));
}
}
}
@Override
public void handleTransportError(
WebSocketSession session, Throwable exception) throws Exception {
log(session.getId() + " 익셉션 발생: " + exception.getMessage());
}
private void log(String logmsg) {
System.out.println(new Date() + " : " + logmsg);
}
}
UserVO , MessageVO , ChatRoomVO, ChatDAO, ChatDAOImpl
package com.almom.domain;
import java.util.Date;
public class UserVO {
private String user_id;
private String user_email;
private String user_name;
private String user_password;
private String user_profileImagePath;
private int user_sex;
private String user_birth;
private String user_job;
private String user_phoneNumber;
private String user_authCode;
private String user_authStatus;
private String user_isTutor;
private String user_status;
private String pageNumber;
private String rnum;
private Date user_log;
private int ages;
private int age_count;
private int user_isAdmin;
private int unReadCount;
public int getUnReadCount() {
return unReadCount;
}
public void setUnReadCount(int unReadCount) {
this.unReadCount = unReadCount;
}
public int getUser_isAdmin() {
return user_isAdmin;
}
public void setUser_isAdmin(int user_isAdmin) {
this.user_isAdmin = user_isAdmin;
}
public int getAges() {
return ages;
}
public void setAges(int ages) {
this.ages = ages;
}
public int getAge_count() {
return age_count;
}
public void setAge_count(int age_count) {
this.age_count = age_count;
}
public Date getUser_log() {
return user_log;
}
public void setUser_log(Date user_log) {
this.user_log = user_log;
}
public String getPageNumber() {
return pageNumber;
}
public void setPageNumber(String pageNumber) {
this.pageNumber = pageNumber;
}
public String getRnum() {
return rnum;
}
public void setRnum(String rnum) {
this.rnum = rnum;
}
public String getUser_status() {
return user_status;
}
public void setUser_status(String user_status) {
this.user_status = user_status;
}
public String getUser_isTutor() {
return user_isTutor;
}
public void setUser_isTutor(String user_isTutor) {
this.user_isTutor = user_isTutor;
}
public String getUser_authCode() {
return user_authCode;
}
public void setUser_authCode(String user_authCode) {
this.user_authCode = user_authCode;
}
public String getUser_authStatus() {
return user_authStatus;
}
public void setUser_authStatus(String user_authStatus) {
this.user_authStatus = user_authStatus;
}
public void setUser_birth(String user_birth) {
this.user_birth = user_birth;
}
public String getUser_birth() {
return user_birth;
}
private String user_snsId;
public void setUser_snsId(String user_snsId) {
this.user_snsId = user_snsId;
}
public String getUser_snsId() {
return user_snsId;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getUser_email() {
return user_email;
}
public void setUser_email(String user_email) {
this.user_email = user_email;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_password() {
return user_password;
}
public void setUser_password(String user_password) {
this.user_password = user_password;
}
public String getUser_profileImagePath() {
return user_profileImagePath;
}
public void setUser_profileImagePath(String user_profileImagePath) {
this.user_profileImagePath = user_profileImagePath;
}
public int getUser_sex() {
return user_sex;
}
public void setUser_sex(int user_sex) {
this.user_sex = user_sex;
}
public String getUser_job() {
return user_job;
}
public void setUser_job(String user_job) {
this.user_job = user_job;
}
public String getUser_phoneNumber() {
return user_phoneNumber;
}
public void setUser_phoneNumber(String user_phoneNumber) {
this.user_phoneNumber = user_phoneNumber;
}
@Override
public String toString() {
return "UserVO [user_id=" + user_id + ", user_email=" + user_email + ", user_name=" + user_name
+ ", user_password=" + user_password + ", user_profileImagePath=" + user_profileImagePath
+ ", user_sex=" + user_sex + ", user_birth=" + user_birth + ", user_job=" + user_job
+ ", user_phoneNumber=" + user_phoneNumber + ", user_authCode=" + user_authCode + ", user_authStatus="
+ user_authStatus + ", user_isTutor=" + user_isTutor + ", user_status=" + user_status + ", pageNumber="
+ pageNumber + ", rnum=" + rnum + ", user_log=" + user_log + ", ages=" + ages + ", age_count="
+ age_count + ", user_isAdmin=" + user_isAdmin + ", unReadCount=" + unReadCount + ", user_snsId="
+ user_snsId + "]";
}
}
package com.almom.domain;
import java.util.Date;
import com.google.gson.Gson;
public class MessageVO {
private String message_id;
private String message_sender;
private String message_receiver;
private String message_content;
private Date message_sendTime;
private Date message_readTime;
private String CHATROOM_chatroom_id;
private String USER_user_id;
private String TUTOR_USER_user_id;
private int CLASS_class_id;
private String user_profileImagePath;
private String receiver_user_profileImagePath;
private String user_name;
private String receiver_user_name;
private String class_name;
private int class_id;
private String TUTOR_tutor_id;
private String tutor_name;
private String tuti_id;
private int unReadCount;
public int getUnReadCount() {
return unReadCount;
}
public void setUnReadCount(int unReadCount) {
this.unReadCount = unReadCount;
}
public String getTuti_id() {
return tuti_id;
}
public void setTuti_id(String tuti_id) {
this.tuti_id = tuti_id;
}
public String getTutor_name() {
return tutor_name;
}
public void setTutor_name(String tutor_name) {
this.tutor_name = tutor_name;
}
public int getClass_id() {
return class_id;
}
public void setClass_id(int class_id) {
this.class_id = class_id;
}
public String getTUTOR_tutor_id() {
return TUTOR_tutor_id;
}
public void setTUTOR_tutor_id(String tUTOR_tutor_id) {
TUTOR_tutor_id = tUTOR_tutor_id;
}
public String getClass_name() {
return class_name;
}
public void setClass_name(String class_name) {
this.class_name = class_name;
}
public String getReceiver_user_name() {
return receiver_user_name;
}
public void setReceiver_user_name(String receiver_user_name) {
this.receiver_user_name = receiver_user_name;
}
public String getUser_profileImagePath() {
return user_profileImagePath;
}
public void setUser_profileImagePath(String user_profileImagePath) {
this.user_profileImagePath = user_profileImagePath;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getReceiver_user_profileImagePath() {
return receiver_user_profileImagePath;
}
public void setReceiver_user_profileImagePath(String receiver_user_profileImagePath) {
this.receiver_user_profileImagePath = receiver_user_profileImagePath;
}
public Date getMessage_sendTime() {
return message_sendTime;
}
public void setMessage_sendTime(Date message_sendTime) {
this.message_sendTime = message_sendTime;
}
public Date getMessage_readTime() {
return message_readTime;
}
public void setMessage_readTime(Date message_readTime) {
this.message_readTime = message_readTime;
}
public String getMessage_id() {
return message_id;
}
public void setMessage_id(String message_id) {
this.message_id = message_id;
}
public String getMessage_sender() {
return message_sender;
}
public void setMessage_sender(String message_sender) {
this.message_sender = message_sender;
}
public String getMessage_receiver() {
return message_receiver;
}
public void setMessage_receiver(String message_receiver) {
this.message_receiver = message_receiver;
}
public String getMessage_content() {
return message_content;
}
public void setMessage_content(String message_content) {
this.message_content = message_content;
}
public String getCHATROOM_chatroom_id() {
return CHATROOM_chatroom_id;
}
public void setCHATROOM_chatroom_id(String cHATROOM_chatroom_id) {
CHATROOM_chatroom_id = cHATROOM_chatroom_id;
}
public String getUSER_user_id() {
return USER_user_id;
}
public void setUSER_user_id(String uSER_user_id) {
USER_user_id = uSER_user_id;
}
public int getCLASS_class_id() {
return CLASS_class_id;
}
public void setCLASS_class_id(int cLASS_class_id) {
CLASS_class_id = cLASS_class_id;
}
public String getTUTOR_USER_user_id() {
return TUTOR_USER_user_id;
}
public void setTUTOR_USER_user_id(String tUTOR_USER_user_id) {
TUTOR_USER_user_id = tUTOR_USER_user_id;
}
public static MessageVO convertMessage(String source) {
MessageVO message = new MessageVO();
Gson gson = new Gson();
message = gson.fromJson(source, MessageVO.class);
return message;
}
@Override
public String toString() {
return "MessageVO [message_id=" + message_id + ", message_sender=" + message_sender + ", message_receiver="
+ message_receiver + ", message_content=" + message_content + ", message_sendTime=" + message_sendTime
+ ", message_readTime=" + message_readTime + ", CHATROOM_chatroom_id=" + CHATROOM_chatroom_id
+ ", USER_user_id=" + USER_user_id + ", TUTOR_USER_user_id=" + TUTOR_USER_user_id + ", CLASS_class_id="
+ CLASS_class_id + ", user_profileImagePath=" + user_profileImagePath
+ ", receiver_user_profileImagePath=" + receiver_user_profileImagePath + ", user_name=" + user_name
+ ", receiver_user_name=" + receiver_user_name + ", class_name=" + class_name + ", class_id=" + class_id
+ ", TUTOR_tutor_id=" + TUTOR_tutor_id + ", tutor_name=" + tutor_name + ", tuti_id=" + tuti_id
+ ", unReadCount=" + unReadCount + "]";
}
}
package com.almom.domain;
public class ChatRoomVO {
private String chatroom_id;
private String USER_user_id;
private String TUTOR_USER_user_id;
private int CLASS_class_id;
public String getChatroom_id() {
return chatroom_id;
}
public void setChatroom_id(String chatroom_id) {
this.chatroom_id = chatroom_id;
}
public String getUSER_user_id() {
return USER_user_id;
}
public void setUSER_user_id(String uSER_user_id) {
USER_user_id = uSER_user_id;
}
public String getTUTOR_USER_user_id() {
return TUTOR_USER_user_id;
}
public void setTUTOR_USER_user_id(String tUTOR_USER_user_id) {
TUTOR_USER_user_id = tUTOR_USER_user_id;
}
public int getCLASS_class_id() {
return CLASS_class_id;
}
public void setCLASS_class_id(int cLASS_class_id) {
CLASS_class_id = cLASS_class_id;
}
@Override
public String toString() {
return "ChatRoomVO [chatroom_id=" + chatroom_id + ", USER_user_id=" + USER_user_id + ", TUTOR_USER_user_id="
+ TUTOR_USER_user_id + ", CLASS_class_id=" + CLASS_class_id + "]";
}
}
package com.almom.persistence;
import java.util.List;
import com.almom.domain.ChatRoomVO;
import com.almom.domain.MessageVO;
public interface ChatDAO {
public void createRoom(ChatRoomVO vo)throws Exception;
public ChatRoomVO isRoom(ChatRoomVO vo)throws Exception;
public void insertMessage(MessageVO vo)throws Exception;
public String getPartner(ChatRoomVO vo)throws Exception;
public String getProfile(String str)throws Exception;
public String getName(String str)throws Exception;
public List<MessageVO> getMessageList(String str)throws Exception;
public List<ChatRoomVO> getRoomList(String str)throws Exception;
public List<ChatRoomVO> getRoomList2(String str)throws Exception;
public MessageVO getRecentMessage(String str)throws Exception;
//public String isGetMessageList(String str)throws Exception;
public String getTutorId(String str)throws Exception;
public List<ChatRoomVO> getRoomListTutor(String str)throws Exception;
public void updateReadTime(int class_id , String user_id , String TUTOR_USER_user_id)throws Exception;
public void updateReadTimeTutor(int class_id , String user_id , String TUTOR_USER_user_id)throws Exception;
public int getUnReadCount(String TUTOR_USER_user_id, int class_id, String user_id)throws Exception;
public int getUnReadCountTutor(String TUTOR_USER_user_id, int class_id, String user_id)throws Exception;
public int getAllCount(String str);
}
package com.almom.persistence;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import com.almom.domain.ChatRoomVO;
import com.almom.domain.MessageVO;
@Repository
public class ChatDAOImpl implements ChatDAO{
@Inject
private SqlSession session;
private static String namespace = "com.almom.mapper.ChatMapper";
@Override
public void createRoom(ChatRoomVO vo) throws Exception {
// TODO Auto-generated method stub
System.out.println("ㅅㅂ");
session.insert(namespace+".createRoom" , vo);
System.out.println("시팔");
}
@Override
public ChatRoomVO isRoom(ChatRoomVO vo) throws Exception {
// TODO Auto-generated method stub
ChatRoomVO roomvo = null;
roomvo = session.selectOne(namespace+".isRoom", vo);
System.out.println("ss");
System.out.println(roomvo);
return roomvo;
}
@Override
public void insertMessage(MessageVO vo) throws Exception {
// TODO Auto-generated method stub
session.insert(namespace+".insertMessage" , vo);
}
@Override
public String getPartner(ChatRoomVO vo) throws Exception {
// TODO Auto-generated method stub
List<MessageVO> mvo = session.selectList(namespace+".getPartner", vo);
return mvo.get(0).getUSER_user_id();
}
@Override
public String getProfile(String str) throws Exception {
// TODO Auto-generated method stub
return session.selectOne(namespace+".getProfile" , str);
}
@Override
public String getName(String str) throws Exception {
// TODO Auto-generated method stub
return session.selectOne(namespace+".getName" , str);
}
@Override
public List<MessageVO> getMessageList(String str) throws Exception {
// TODO Auto-generated method stub
return session.selectList(namespace+".getMessageList" , str);
}
@Override
public List<ChatRoomVO> getRoomList(String str) throws Exception {
// TODO Auto-generated method stub
return session.selectList(namespace+".getRoomList",str);
}
@Override
public List<ChatRoomVO> getRoomList2(String str) throws Exception {
// TODO Auto-generated method stub
return session.selectList(namespace+".getRoomList2" , str);
}
@Override
public MessageVO getRecentMessage(String str) throws Exception {
// TODO Auto-generated method stub
return session.selectOne(namespace+".getRecentMessage" , str);
}
@Override
public String getTutorId(String str) throws Exception {
// TODO Auto-generated method stub
return session.selectOne(namespace+".getTutorId" , str) ;
}
@Override
public List<ChatRoomVO> getRoomListTutor(String str) throws Exception {
// TODO Auto-generated method stub
return session.selectList(namespace+".getRoomListTutor" , str);
}
@Override
public void updateReadTime(int class_id, String user_id, String TUTOR_USER_user_id) throws Exception {
// TODO Auto-generated method stub
HashMap<String, Object> map = new HashMap<String, Object> ();
map.put("TUTOR_USER_user_id", TUTOR_USER_user_id);
map.put("USER_user_id", user_id);
map.put("CLASS_class_id", class_id);
session.update(namespace+".updateReadTime" , map);
}
@Override
public int getUnReadCount(String TUTOR_USER_user_id, int class_id, String user_id) throws Exception {
// TODO Auto-generated method stub
HashMap<String, Object> map = new HashMap<String, Object> ();
map.put("TUTOR_USER_user_id", TUTOR_USER_user_id);
map.put("USER_user_id", user_id);
map.put("CLASS_class_id", class_id);
return session.selectOne(namespace+".getUnReadCount" , map);
}
@Override
public int getAllCount(String str) {
// TODO Auto-generated method stub
HashMap<String, Object> map = new HashMap<String, Object> ();
map.put("USER_user_id", str);
map.put("TUTOR_USER_user_id", str);
if(session.selectOne(namespace+".getAllCount" ,map) ==null) {
return 0;
}else {
return session.selectOne(namespace+".getAllCount" ,map);
}
}
@Override
public void updateReadTimeTutor(int class_id , String user_id , String TUTOR_USER_user_id) throws Exception {
// TODO Auto-generated method stub
HashMap<String, Object> map = new HashMap<String, Object> ();
map.put("TUTOR_USER_user_id", TUTOR_USER_user_id);
map.put("USER_user_id", user_id);
map.put("CLASS_class_id", class_id);
session.update(namespace+".updateReadTimeTutor" , map);
}
@Override
public int getUnReadCountTutor(String TUTOR_USER_user_id, int class_id, String user_id) throws Exception {
// TODO Auto-generated method stub
HashMap<String, Object> map = new HashMap<String, Object> ();
map.put("TUTOR_USER_user_id", TUTOR_USER_user_id);
map.put("USER_user_id", user_id);
map.put("CLASS_class_id", class_id);
return session.selectOne(namespace+".getUnReadCountTutor" , map);
}
}
SQL(ChatMapper.xml)
<?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="com.almom.mapper.ChatMapper">
<insert id = "createRoom">
insert into CHATROOM (USER_user_id , TUTOR_USER_user_id, CLASS_class_id)
values(#{USER_user_id}, #{TUTOR_USER_user_id} , #{CLASS_class_id} )
</insert>
<select id ="isRoom" resultType = "ChatRoomVO">
select * from CHATROOM WHERE USER_user_id = #{USER_user_id} and TUTOR_USER_user_id = #{TUTOR_USER_user_id}
and CLASS_class_id = #{CLASS_class_id}
</select>
<insert id = "insertMessage">
insert into MESSAGE (message_sender , message_receiver, message_content,
CHATROOM_chatroom_id, USER_user_id , TUTOR_USER_user_id, CLASS_class_id)
values (#{message_sender}, #{message_receiver}, #{message_content} , #{CHATROOM_chatroom_id} , #{USER_user_id},
#{TUTOR_USER_user_id} , #{CLASS_class_id})
</insert>
<select id = "getPartner" resultType = "MessageVO">
SELECT USER_user_id from MESSAGE where TUTOR_USER_user_id = #{TUTOR_USER_user_id} and CLASS_class_id = #{CLASS_class_id}
</select>
<select id = "getProfile" resultType = "String">
select user_profileImagePath from USER WHERE user_id = #{user_id}
</select>
<select id = "getName" resultType = "String">
select user_name from USER where user_id = #{user_id}
</select>
<select id = "getMessageList" resultType = "MessageVO">
select m.* , user_name, user_profileImagePath from MESSAGE m left outer join USER u on m.message_sender = u.user_id where CHATROOM_chatroom_id = #{CHATROOM_chatroom_id}
</select>
<select id = "getRoomList" resultType = "ChatRoomVO">
select * from CHATROOM where USER_user_id = #{USER_user_id}
</select>
<select id = "getRoomList2" resultType = "ChatRoomVO">
select * from CHATROOM where TUTOR_USER_user_id = #{TUTOR_USER_user_id}
</select>
<select id = "getRecentMessage" resultType = "MessageVO">
select m.* , class_name, class_id , TUTOR_tutor_id from MESSAGE m left outer join CLASS c on m.CLASS_class_id = c.class_id
where CHATROOM_chatroom_id = #{CHATROOM_chatroom_id} order by message_id desc limit 1;
</select>
<select id = "getTutorId" resultType = "String">
select tutor_id from TUTOR where USER_user_id = #{USER_user_id}
</select>
<update id ="updateReadTime">
update MESSAGE set message_readTime = NOW() where TUTOR_USER_user_id = #{TUTOR_USER_user_id} AND CLASS_class_id = #{CLASS_class_id} AND message_readTime = message_sendTime and message_sender = TUTOR_USER_user_id and USER_user_id = #{USER_user_id};
</update>
<update id ="updateReadTimeTutor">
update MESSAGE set message_readTime = NOW() where TUTOR_USER_user_id = #{TUTOR_USER_user_id} AND CLASS_class_id = #{CLASS_class_id} AND message_readTime = message_sendTime and message_sender = USER_user_id and USER_user_id = #{USER_user_id};
</update>
<select id = "getUnReadCount" resultType = "int">
select count(*) from MESSAGE where USER_user_id = #{USER_user_id} and TUTOR_USER_user_id = #{TUTOR_USER_user_id} AND CLASS_class_id = #{CLASS_class_id} AND message_readTime = message_sendTime and message_sender = TUTOR_USER_user_id;
</select>
<select id = "getUnReadCountTutor" resultType = "int">
select count(*) from MESSAGE where TUTOR_USER_user_id =#{TUTOR_USER_user_id} and CLASS_class_id = #{CLASS_class_id} AND message_readTime = message_sendTime and message_sender = USER_user_id and USER_user_id = #{USER_user_id};
</select>
<select id = "getAllCount" resultType = "int">
select count(*) from MESSAGE WHERE (TUTOR_USER_user_id = #{TUTOR_USER_user_id} and message_readTime = message_sendTime and message_sender != #{USER_user_id}) or (USER_user_id = #{USER_user_id} and message_readTime = message_sendTime and message_sender != #{USER_user_id});
</select>
</mapper>
최종 구현 화면