좋아요 기능을 만들기 전에
알림 기능이 있으면 좋겠다!라고 생각했고
여기에 웹 소켓 기능을 추가하기로 했다.
아직은 기본적인 단계이다.
먼저 pom.xml에 웹 소켓을 추가해준다.
<!-- socket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework-version}</version>
</dependency>
그 후,
servlet-context.xml
<!-- websocket -->
<websocket:handlers>
<websocket:mapping handler="myHandler" path="/alarm" />
<websocket:sockjs websocket-enabled="true"/>
</websocket:handlers>
<beans:bean id="myHandler" class="kr.co.korea.handler.WebSocketHandler" />
위와 같이 추가해준다.
mapping의 경우 handler를 설정하는데
경로를 /alarm로 해주고 이름을 myHandler라고 설정해줬다.
그리고 sockjs를 사용하므로 true로 설정해준다.(이렇게 안 하면 계속해서 오류가 난다.)
그다음 지정해준 bean의 클래스를 만들어준다.
public class WebSocketHandler extends TextWebSocketHandler{
private static final Logger logger = LoggerFactory.getLogger(WebSocketHandler.class);
//로그인 한 인원 전체
private List<WebSocketSession> sessions = new ArrayList<WebSocketSession>();
// 1:1로 할 경우
private Map<String, WebSocketSession> userSessionsMap = new HashMap<String, WebSocketSession>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {//클라이언트와 서버가 연결
// TODO Auto-generated method stub
logger.info("Socket 연결");
sessions.add(session);
logger.info(currentUserName(session));//현재 접속한 사람
userSessionsMap.put(currentUserName(session),session);
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {// 메시지
// TODO Auto-generated method stub
String msg = message.getPayload();//자바스크립트에서 넘어온 Msg
if(msg != null) {
String[] msgs = msg.split(",");
if(msgs != null && msgs.length ==3) {
String bid = msgs[0];//게시물 번호
String receiver = msgs[1];//글 작성자
String count = msgs[2];//0이면 좋아요 취소 1이면 좋아요
String btitle = msgs[3];//게시물 제목
String comment = "";
if(count.equals("0")) {
comment = "의 좋아요를 취소했습니다.";
}else if(count.equals("1")) {
comment = "을 좋아합니다.";
}
String mid = currentUserName(session);//좋아요 누른 사람
WebSocketSession receiversession = userSessionsMap.get(receiver);//글 작성자가 현재 접속중인가 체크
if(receiversession !=null) {
TextMessage txtmsg = new TextMessage(mid+"님이" + receiver + "님의" + btitle + comment);
receiversession.sendMessage(txtmsg);//작성자에게 알려줍니다
}else {
TextMessage txtmsg = new TextMessage(mid+"님이" + receiver + "님의" + btitle + comment);
session.sendMessage(txtmsg);//보내지는지 체크하기
}
}
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {//연결 해제
// TODO Auto-generated method stub
logger.info("Socket 끊음");
sessions.remove(session);
userSessionsMap.remove(currentUserName(session),session);
}
private String currentUserName(WebSocketSession session) {
String mid = session.getPrincipal().getName();
return mid;
}
위와 같이 작성해준다.
list는 전체 알람, 혹은 전체 채팅을 원할 경우 작성(이에 대한 코드는 아직 작성 안 했다..)
그리고 map은 반드시 추가해줘야 한다.
왜냐하면 본인이 특정 누군가의 게시물의 좋아요를 눌렀는데
해당 유저가 접속했는지 안 했는지를 Hashmap으로 알아내기 때문이다.
afterConnectionEstablished (WebSocketSession session) |
소켓과 연결 됬을 때 |
handleTextMessage (WebSocketSession session, TextMessage message) |
메시지 |
afterConnectionClosed (WebSocketSession session, CloseStatus status) |
소켓과 연결이 끊겼을 때 |
currentUserName (WebSocketSession session) |
현재 접속한 유저의 id(시큐리티를 이용해서 getPrincipal()) |
이 중에서도 handleTextMessag에 대해서 이야기하자면
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {// 메시지
// TODO Auto-generated method stub
String msg = message.getPayload();//자바스크립트에서 넘어온 Msg
if(msg != null) {
String[] msgs = msg.split(",");
if(msgs != null && msgs.length ==4) {
String bid = msgs[0];//게시물 번호
String receiver = msgs[1];//글 작성자
String count = msgs[2];//0이면 좋아요 취소 1이면 좋아요
String btitle = msgs[3];//게시물 제목
String comment = "";
if(count.equals("0")) {
comment = "의 좋아요를 취소했습니다.";
}else if(count.equals("1")) {
comment = "을 좋아합니다.";
}
String mid = currentUserName(session);//좋아요 누른 사람
WebSocketSession receiversession = userSessionsMap.get(receiver);//글 작성자가 현재 접속중인가 체크
if(receiversession !=null) {
TextMessage txtmsg = new TextMessage(mid+"님이" + receiver + "님의" + btitle + comment);
receiversession.sendMessage(txtmsg);//작성자에게 알려줍니다
}else {
TextMessage txtmsg = new TextMessage(mid+"님이" + receiver + "님의" + btitle + comment);
session.sendMessage(txtmsg);//보내지는지 체크하기
}
}
}
}
맨 아랫부분에 receiversession부분을 보면
본인의 session이 아니라 글 작성자의 session이기 때문에
현재 확인을 하지 못한다. 그래서 else로 null일 경우
다시 자신에게 그 msg를 보내도록 설정 해 두었다.
그다음 view로 가서
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
CDN을 추가해준다.
그 다음 index.js를 만든 후
var sock = null;
$(document).ready(function(){
connectWs();
});
function connectWs(){
sock = new SockJS(getContextPath()+'/alarm');
sock.onopen = function() {
console.log('open');
};
sock.onmessage = function(e) {
console.log('message', e.data);
// sock.close();
};
sock.onclose = function() {
console.log('close');
};
};
function getContextPath() {
var hostIndex = location.href.indexOf( location.host ) + location.host.length;
return location.href.substring( hostIndex, location.href.indexOf('/', hostIndex + 1) );
};
위와 같이 작성해준다.
최소한의 정보만 표시하고 있다.(아직 알람이 보이게 할 span을 만들지 않아서...)
그리고 이러한 소켓을 이용할 때는
sock.send()가 있어야 만한다.(onopen에서 handler로 )
sock.send는 좋아요를 눌렀을 때
실행이 돼야 하므로 좋아요 부분의 ajax로 가준다.
function likeupdate(){
var root = getContextPath(),
likeurl = "/like/likeupdate",
mid = $('#mid').val(),
bid = $('#bid').val(),
receiver = $('#bwriter').val(),
btitle = $('#btitle').val(),
count = $('#likecheck').val(),
data = {"ltmid" : mid,
"ltbid" : bid,
"count" : count};
$.ajax({
url : root + likeurl,
type : 'PUT',
contentType: 'application/json',
data : JSON.stringify(data),
success : function(result){
console.log("수정" + result.like);
if(count == 1){
console.log("좋아요 취소");
$('#likecheck').val(0);
$('#likebtn').attr('class','btn btn-light');
$('#likecount').html(result.like);
if(sock){
var Msg = bid+","+receiver+","+count+","+btitle;
console.log(Msg);
sock.send(Msg);
}
}else if(count == 0){
console.log("좋아요!");
$('#likecheck').val(1);
$('#likebtn').attr('class','btn btn-danger');
$('#likecount').html(result.like);
if(sock){
var Msg = bid+","+receiver+","+count+","+btitle;
console.log(Msg);
sock.send(Msg);
}
}
}, error : function(result){
console.log("에러" + result.result)
}
});
};
이와 같이 기존에 어느 시점을 정해서
그 시점에 if(sock)를 해준 후 sock.send를 해주면 된다.
이렇게 해주면.
좋아요를 누른 경우
좋아요를 취소한 경우
와 같이 작동되고 있는 것을 알 수 있습니다.
이다음에는
DB를 만들어서
console.log가 아니라 표시되게 만들어 보겠습니다.
'spring > 게시판' 카테고리의 다른 글
스프링 게시판 만들기 좋아요(2) (0) | 2021.04.24 |
---|---|
스프링 게시판 좋아요 버튼 (0) | 2021.04.24 |
스프링 Rest CRUD 구현 (0) | 2021.04.07 |
스프링 시큐리티 예제 (0) | 2021.04.07 |
스프링 이미지 업로드 (0) | 2021.03.11 |