뷰 관점에서 본 코드 흐름

 

컨트롤러 패키지 구조입니다.

뷰 폴더 구조입니다.

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
package com.dms.controller;
 
 
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.dms.chat.ChatRoom;
import com.dms.chat.ChatRoomRepository;
 
@Controller
@RequestMapping("/multiRoom")
public class home {
 
    @GetMapping("/home")
    public String homeController(Model model, HttpServletRequest request) {
        Collection<ChatRoom> chatRooms = ChatRoomRepository.chatRooms;
        
        model.addAttribute("collection", chatRooms);
        return "home";
    }
}
 
cs

home 컨트롤러(클래스)입니다.

모델로 chatRooms 변수를 사용합니다.

++) ChatRoomRepository 클래스의 chatRooms 변수에 public static을 붙여놓았습니다.

그러므로 초기화된 chatRooms 변수를 home 클래스에서 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="java.util.*"%>    
<%@page import="com.dms.chat.ChatRoom"%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>대기방</title>
</head>
<body>
<%
    Collection<ChatRoom> col = (Collection<ChatRoom>) request.getAttribute("collection");
    Iterator<ChatRoom> it = col.iterator();    
    while(it.hasNext()) {        
        String roomId = it.next().getId();
%>
<p>
<div><a href="room?id=<%=roomId%>"><%=roomId%></a></div>
</p>
<%} %>
</body>
</html>
cs

home 뷰(jsp) 입니다.

모델로 받은 collection변수안에 있는 roomId를 가져옵니다.   

collection변수에는 초기화된 String 타입의 id 변수를 가진 클래스 두개가 들어있습니다.

Iterator 의 next메소드를 통해 클래스를 가져옵니다.

그리고 그 클래스의 getId 메소드로 id 변수(roomId)를 가져옵니다.

 

가져온 roomId는 <a>태그에서 url 파라미터로 사용합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.dms.controller;
 
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
@RequestMapping("/multiRoom")
public class room {
 
    @GetMapping("/room")
    public String roomController(Model model, HttpServletRequest request) {
        String roomId = request.getParameter("id");
        
        model.addAttribute("roomId", roomId);
        return "room";
    }
}
 
cs

room 컨트롤러(클래스) 입니다.

<a> 태그에서 적어준 id(roomId)를 roomId 변수에 넣습니다.

 그리고 roomId 변수를 모델에 추가합니다.

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
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>대화방</title>
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script>
var roomId = "${roomId}";
var sock = new SockJS("/ws/multiRoom");
 
/*onopen 함수는 페이지가 로드되면 자동실행됨*/
sock.onopen = function () {
    sock.send( JSON.stringify({chatRoomId: roomId, type: "JOIN"}) );
}                                                                            
/*onmessage 함수는 메시지가 오면 자동실행됨*/    
    sock.onmessage = function (e) {
        var content = JSON.parse(e.data);
        var message = content.message;
        var type = content.type;
        var chatLog = document.getElementById("chatLog");     
        if(type == "SEND")
            chatLog.innerHTML = chatLog.innerHTML + "<p>" + message + "</p>";
}
    
function send(){
    var textarea = document.getElementById("textarea");
    var myMessage = textarea.value;
    sock.send( JSON.stringify({chatRoomId: roomId, type: "SEND", message: myMessage}) );
}    
</script>    
</head>
<body>
<h1>대화방</h1>
<div id="chatLog"></div>
<textarea id="textarea"></textarea>
<input type="button" value="전송" onclick="send()">
</body>
</html>
cs

room 뷰(jsp) 입니다.

room 뷰에서는 두가지 일이 일어납니다.

1) onopen

2) onmessage

 

onopen

room에 들어가면 sock.onopen 함수가 실행됩니다.

그리고, sock.send 함수가 실행됩니다.

js 변수인 roomId는 모델로 초기화 됩니다.

sock.send가 실행될 때, roomId와 type이 사용됩니다.

이 데이터들은 chatHandler 을 거쳐서 ChatRoom 클래스에 오게됩니다.

type이 "JOIN" 이므로 ChatRoom 클래스의 ssessions변수에 접속한 사용자 세션 정보를 등록합니다.

 

onmessage

room 뷰 화면

메시지를 입력하고 전송 버튼을 클릭하면  send 함수(js)가 실행됩니다.

그리고 sock.send 함수가 실행됩니다.

sock.send가 실행될 때, roomId, type, messsage 들이 사용됩니다.

이 데이터들은 chatHandler 을 거쳐서 ChatRoom 클래스에 오게됩니다.

type이 "SEND" 이므로 ChatRoom 클래스의 send메소드가 실행됩니다.

 

같은 방끼리만 메시지를 공유하는 다중채팅방이 완성되었습니다. 

github.com/burnaby033/springboot_multiroom

 

burnaby033/springboot_multiroom

스프링부트 다중채팅방, 스프링부트 멀티 채팅방. Contribute to burnaby033/springboot_multiroom development by creating an account on GitHub.

github.com

프로젝트 다운 주소입니다.

 

++) supawer0728.github.io/2018/03/30/spring-websocket/

 

Spring WebSocket 소개

서론Web Browser에서 Request를 보내면 Server는 Response를 준다. HTTP 통신의 기본적인 동작 방식이다. 하지만 Server에서 Client로 특정 동작을 알려야 하는 상황도 있다. 예를 들어 Browser로 Facebook에 접속해

supawer0728.github.io

이 프로젝트의 원본 코드입니다.

(SockJS 부분)

+ Recent posts