출처: https://bumcrush.tistory.com/182 [맑음때때로 여름]

 

1 lib 세팅

 

pom.xml

websocket과 잭슨바인드 json을 자바의 객체로 쉽게 변경할 수 있는 gson을 넣어준다.

 

2 채팅을 위한 핸들러 클래스 정의

TextWebSocketHandler 상속해서 정의 - 접속 / 퇴장 / 메세지 전송

ace - 접속, htm - 메세지 전송, close -로그아웃 , List/Map = 저장공간

package com.aia.socket.handler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.aia.socket.domain.Message;
import com.google.gson.Gson;
public class EchoHandler extends TextWebSocketHandler {
private static final Logger logger = LoggerFactory.getLogger(EchoHandler.class);
private List<WebSocketSession> sessionList = new ArrayList<WebSocketSession>();
private Map<String, WebSocketSession> sessionMap = new HashMap<String, WebSocketSession>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String chatMember = (String) session.getAttributes().get("user");
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>" + chatMember);
// 저장! 둘중에 하나 사용하면 되는데, 선생님은 둘다 넣어두심
sessionList.add(session);
// sessionMap.put(chatMember, session);
logger.info("{} 연결되었습니다.", session.getId()+":"+chatMember);
System.out.println("체팅 참여자 : " + chatMember);
}
@Override //메세지보내기 //누가보냈는지에 대한 정보저장↓
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// 현재 로그인된 멤버
String chatMember = (String) session.getAttributes().get("user");
logger.info("{}로 부터 {}를 전달 받았습니다.", chatMember, message.getPayload());
Gson gson = new Gson();
//json으로부터 객체를 만듦 //이 message클래스를 기반으로 json이만들어진다.
Message msg = gson.fromJson(message.getPayload(), Message.class);
// ↑ json을 java의 객체로 바꿔주는 것. // user, to, articleId, articleOwnver(방장?), message;
System.out.println(msg);
// 전달 메시지
TextMessage sendMsg = new TextMessage(gson.toJson(msg));
// sessionList 모두에게, afterConnectionEstablished에서 들어오는 인간들 저장했었음
for (WebSocketSession webSocketSession : sessionList) {
// 상대방에게 메시지 전달
webSocketSession.sendMessage(sendMsg);
}
// 자신에게 메시지 전달
//session.sendMessage(sendMsg);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// 현재 유저 - 로그아웃
String chatMember = (String) session.getAttributes().get("user");
sessionList.remove(session);
logger.info("{} 연결이 끊김", session.getId()+chatMember);
System.out.println("체팅 퇴장 : " + chatMember);
}
}
package com.aia.socket.domain;
public class Message {
private String user;
private String to;
private String articleId;
private String articleOwner;
private String message;
public Message(String user, String to, String articleId, String articleOwner, String message) {
this.user = user;
this.to = to;
this.articleId = articleId;
this.articleOwner = articleOwner;
this.message = message;
}
public Message() {
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getArticleId() {
return articleId;
}
public void setArticleId(String articleId) {
this.articleId = articleId;
}
public String getArticleOwner() {
return articleOwner;
}
public void setArticleOwner(String articleOwner) {
this.articleOwner = articleOwner;
}
@Override
public String toString() {
return "Message [user=" + user + ", to=" + to + ", articleId=" + articleId + ", articleOwner=" + articleOwner
+ ", message=" + message + "]";
}
}

 

3. Spring-socket.xml 설정 파일 정의

 

설정파일 : 웹소켓 핸들러 bean 등록 

// handshake-interceptors = httpsession을 웹소켓세션으로 쓸 수 있게 해준다(?)

 

 

설정파일 : web.xml에 등록해주기!

 

 

4.

 

package com.aia.socket.controller;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ChattingController {
@RequestMapping("/chatting")
public ModelAndView chat(
ModelAndView mv,
@RequestParam("uid") String uid,
HttpSession session
) {
mv.setViewName("chat/chat");
mv.addObject("user", uid);
mv.addObject("articleId", "12345");
mv.addObject("articleOwner", "jin");
session.setAttribute("user", uid);
return mv;
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
.text_right {
text-align: right;
}
.text_left {
text-align: left;
}
.chattingBox {
padding : 15px;
border : 1px solid #AAA;
margin: 10px 0;
}
</style>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<!-- 웹소켓 객체를 가져올 수 있게해준다 -->
<script
src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
<!-- Zebra-Dialog CDN -->
<!-- <script src="resources/js/dialog/zebra_dialog.src.js"></script>
<link rel="stylesheet" href="resources/css/dialog/zebra_dialog.css" type="text/css" /> -->
</head>
<body>
<h1>Chatting Page (id: ${user})</h1>
<br>
<form>
<div>
<div>
<input type="text" id="message" />
<input type="submit" id="sendBtn" value="전송" />
</div>
<br>
<div class="well" id="chatdata">
<!-- User Session Info Hidden -->
<input type="hidden" value='${user}' id="sessionuserid">
</div>
</div>
</form>
</body>
<script>
//websocket을 지정한 URL로 연결
var sock = new SockJS("<c:url value="/echo"/>");
//websocket 서버에서 메시지를 보내면 자동으로 실행된다.
sock.onmessage = onMessage;
//websocket 과 연결을 끊고 싶을때 실행하는 메소드
sock.onclose = onClose;
$(document).ready(function(){
$("form").submit(function() {
console.log('send message...');
sendMessage();
$('#message').val('');
$('#message').focus();
return false;
});
});
$(function() {
});
function sendMessage() {
//websocket으로 메시지를 보내기
var msg = {
user : '${user}',
to : 'jin', // 현재 페이지 작성자의 id를 작성 (강제로하나써놈예제로)
articleId : '${articleId}',
articleOwner : '${articleOwner}',
message : $("#message").val()
};
sock.send(JSON.stringify(msg));
}
//evt 파라미터는 websocket이 보내준 데이터다.
function onMessage(evt) { //변수 안에 function자체를 넣음.
var data = evt.data; // 전달 받은 데이터
//alert(data);
msgData = JSON.parse(data);
var sessionid = null;
var message = null;
//current session id//
var currentuser_session = $('#sessionuserid').val();
console.log('current session id: ' + currentuser_session);
var target = $('#chattingBox-1');
if(target.length==0){
$('<div id=\"chattingBox-1\" class=\"chattingBox\"></div>').html('<h3>${user} : 게시물 작성자-'+msgData.articleOwner+'</h3>').appendTo('body');
$('#chattingBox-1').append('<hr>')
}
// 나와 상대방이 보낸 메세지를 구분하여 출력
if (msgData.user == currentuser_session) {
var printHTML = "<div class='well text_right'>";
printHTML += "<div class='alert alert-info'>";
printHTML += "<strong>[" + msgData.user + "] -> " + msgData.message
+ "</strong>";
printHTML += "</div>";
printHTML += "</div>";
$('#chattingBox-1').append(printHTML);
} else {
var printHTML = "<div class='well text_left'>";
printHTML += "<div class='alert alert-warning'>";
printHTML += "<strong>[" + msgData.user + "] -> " + msgData.message
+ "</strong>";
printHTML += "</div>";
printHTML += "</div>";
$('#chattingBox-1').append(printHTML);
}
console.log('chatting data: ' + data);
/* sock.close(); */
}
function onClose(evt) {
$("#data").append("연결 끊김");
}
</script>
</html>

+ Recent posts