Framework/Spring Framework

(23.01.02)Spring ํ”„๋ ˆ์ž„์›Œํฌ: ์›น์†Œ์ผ“์„ ์ด์šฉํ•œ ์ฑ„ํŒ…ํ”„๋กœ๊ทธ๋žจ ๋งŒ๋“ค๊ธฐ

ํ”„๋กœ๊ทธ๋ž˜๋จธ ์˜ค์›” 2023. 1. 2.

โ—โ— ์›น์†Œ์ผ“โ—โ—


    - Thymeleaf, Websocket
    - HttpSession ์ „๋‹ฌ(Controller -> WebSocket)
    - Interceptor ๋ฐฉ์‹์œผ๋กœ ServletContext ์ „๋‹ฌ
    - page, request, session, application
    - application : ์›น์„œ๋ฒ„์— ํ•œ๊ฐœ๋งŒ ์กด์žฌ
    - application = ServletContext
    - Controller์—์„œ ServletContext ์— HttpSession์˜ ์ฐธ์กฐ๋ฅผ ์ €์žฅ
    - ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ํ†ตํ•ด ServletContext ๋ฅผ WebSocket์œผ๋กœ ์ „๋‹ฌ
    - WebSocket์—์„œ๋Š” WebSocketSession์„ ํ†ตํ•ด์„œ ์ „๋‹ฌ๋œ ์†์„ฑ ๊ฐ’์„ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ๋‹ค
    - WebSocket์—์„œ๋Š” ๋จผ์ € ServletContext๋ฅผ ์ถ”์ถœํ•˜๊ณ  ServletContext๋ฅผ ํ†ตํ•ด
    HttpSession๊ฐ์ฒด๋ฅผ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ๋‹ค

 

applicaation < jsp์—์„œ ๋ถ€๋ฅด๋Š” ๋ง (์˜์—ญ ๊ฐ์ฒด) ์„œ๋ฒ„์—์„  ServletContext๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

 


 

โ—โ—์ „์ฒด ์ฑ„ํŒ…๋ฐฉ ๋งŒ๋“ค๊ธฐโ—โ—

 

 

WebSocketConfiguration.java

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
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import lombok.extern.slf4j.Slf4j;
 
@Slf4j
@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer
{
   private final static String CHAT_ENDPOINT="/ws/chat";
   
   @Override
   public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
      
      registry.addHandler(getChatWebSocketHandler(), CHAT_ENDPOINT)
            .addInterceptors(new HttpHandshakeInterceptor())
            .setAllowedOrigins("*");
      // ์œ„์—์„œ ์ง€์ •ํ•œ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ํ†ตํ•ด WebSocketHandler์—๊ฒŒ ํ•„์š”ํ•œ ์†์„ฑ๋“ค์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค
      log.info("์›น์†Œ์ผ“ ํ•ธ๋“ค๋Ÿฌ ๋“ฑ๋ก ์™„๋ฃŒ");
   }
   
   @Bean
   public WebSocketHandler getChatWebSocketHandler() {
      return new WebSocketHandler();
   }
}
cs

 

 

 

WSChatController.java

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
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.web.bind.annotation.RequestParam;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
 
@Slf4j
@Controller
@RequestMapping("/ws")
public class WSChatController 
{
   @GetMapping("/")
   public String index(HttpServletRequest req)
   {   
      return "thymeleaf/index"
   } 
   
   @GetMapping("/in")   //  localhost/ws/in?userid=smith  ํ˜•์‹์œผ๋กœ ์š”์ฒญํ•˜์—ฌ ๋กœ๊ทธ์ธ ํ…Œ์ŠคํŠธ
   public String chatForm(HttpServletRequest request, @RequestParam("userid")String userid, Model model)
   {   
      model.addAttribute("userid", userid);
 
      HttpSession session = request.getSession();
      log.info("์ƒ์„ฑ๋œ ์„ธ์…˜ ID={}", session.getId());
 
      //HttpSession์„ ServletContext ์˜์—ญ์— ์ €์žฅํ•˜๋ฉด ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ๊ฑฐ์ณ WebSocketHandler์—๊ฒŒ ์ „๋‹ฌ๋จ
      request.getServletContext().setAttribute("httpSession", session);
      session.setAttribute("userid", userid);
      
      log.info("๋กœ๊ทธ์ธ ์„ฑ๊ณต({}), session={}", userid, session.getId());
      
      return "thymeleaf/chat";
   }
}
cs

 

 

 

HttpHandshakeInterceptor.java

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
import java.util.Map;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.server.HandshakeInterceptor;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
 
@Slf4j 
public class HttpHandshakeInterceptor implements HandshakeInterceptor 
{
   @Override
   public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
         org.springframework.web.socket.WebSocketHandler wsHandler, Map<String, Object> attributes)
         throws Exception {
      if (request instanceof ServletServerHttpRequest) {
         
         //ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋œ attributes ์— ์†์„ฑ์„ ์„ค์ •ํ•ด์ฃผ๋ฉด WebSocketHandler์•ˆ์˜ WebSocketSession์œผ๋กœ ์ „๋‹ฌ๋จ
         
         Object obj = ((ServletServerHttpRequest) request).getServletRequest().getServletContext().getAttribute("httpSession");
         HttpSession session = (HttpSession) obj;
         attributes.put("httpSession", session);  // WebSocketHandler์—๊ฒŒ HttpSession ์ „๋‹ฌ
         
         log.info("์ธํ„ฐ์…‰ํ„ฐ, ์„ธ์…˜ ID={}", session.getId());
      }
      return true;
   }
 
   @Override
   public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
         org.springframework.web.socket.WebSocketHandler wsHandler, Exception exception) {
      // TODO Auto-generated method stub
      
   }
}
cs

 

 

 

WebSocketHandler.java

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
41
42
43
44
45
46
47
48
49
 
import java.util.ArrayList;
import java.util.List;
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 jakarta.servlet.http.HttpSession;
import jakarta.websocket.OnOpen;
import lombok.extern.slf4j.Slf4j;
 
@Slf4j
public class WebSocketHandler extends TextWebSocketHandler 
{
   private final List<WebSocketSession> webSocketSessions = new ArrayList<>();
   
   @Override  /* ํด๋ผ์ด์–ธํŠธ ์ ‘์†์‹œ์— ํ˜ธ์ถœ๋จ */
   public void afterConnectionEstablished(WebSocketSession session) throws Exception {
      webSocketSessions.add(session);
      System.out.println("Client Connected");
       
      //์ธํ„ฐ์…‰ํ„ฐ์— ์˜ํ•ด HttpSession์˜ ์†์„ฑ์€ ์•„๋ž˜์ฒ˜๋Ÿผ WebSocketSession๊ฐ์ฒด๋กœ ์ „๋‹ฌ๋˜์–ด ์—ฌ๊ธฐ์„œ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค
      HttpSession httpSession = (HttpSession)session.getAttributes().get("httpSession");
      log.info("์›น์†Œ์ผ“ํ•ธ๋“ค๋Ÿฌ, httpSession={}", httpSession.getId());  // ์ปจํŠธ๋กค๋Ÿฌ์˜ ์„ธ์…˜id์™€ ๋™์ผํ•œ์ง€ ํ™•์ธ
      String userid = (String)httpSession.getAttribute("userid");
      log.info("์›น์†Œ์ผ“ํ•ธ๋“ค๋Ÿฌ, userid={}", userid);
   }
 
   @Override  /* ์„œ๋ฒ„์— ๋ฉ”์‹œ์ง€ ๋„์ฐฉ์‹œ ํ˜ธ์ถœ๋จ */
   protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
      System.out.println("Text Message:"+ message);
      for(WebSocketSession webSocketSession: webSocketSessions) {
         webSocketSession.sendMessage(message);
      }
   }
 
   @Override   /* ์ ‘์† ํ•ด์ œ์‹œ ํ˜ธ์ถœ๋จ */
   public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
      System.out.println("Connection Closed");
      webSocketSessions.remove(session);
   }
 
   @Override   /* ์˜ค๋ฅ˜ ๋ฐœ์ƒ์‹œ ํ˜ธ์ถœ๋จ */
   public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
      System.out.println("Error:" + exception);
      super.handleTransportError(session, exception);
   }
 
 
cs

 

 

 

chat.html

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>์›น์†Œ์ผ“ ํ…Œ์ŠคํŠธ ํŽ˜์ด์ง€</title>
<script type="text/javascript">
 
var userid = '[[${userid}]]';
alert('userid=' + userid);
 
var g_webSocket = null;
window.onload = function() {
    host = "192.168.0.94";   /* ๋ฐฐํฌ์‹œ์— ํ˜ธ์ŠคํŠธ ์ฃผ์†Œ๋กœ ๋ณ€๊ฒฝ */
   //host = "localhost";
    g_webSocket = new WebSocket("ws://"+host+"/ws/chat");
    
    
    /* ์›น์†Œ์ผ“ ์ ‘์† ์„ฑ๊ณต์‹œ ์‹คํ–‰ */
    g_webSocket.onopen = function(message) {
        addLineToChatBox("Server is connected.");
    };
    
    
    /* ์›น์†Œ์ผ“ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹ ์‹œ ์‹คํ–‰ */
    g_webSocket.onmessage = function(message) {
        addLineToChatBox(message.data);
    };
 
    /* ์›น์†Œ์ผ“ ์ด์šฉ์ž๊ฐ€ ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•˜๋Š” ๊ฒฝ์šฐ ์‹คํ–‰ */
    g_webSocket.onclose = function(message) {
        addLineToChatBox("Server is disconnected.");
    };
 
    /* ์›น์†Œ์ผ“ ์—๋Ÿฌ ๋ฐœ์ƒ์‹œ ์‹คํ–‰ */
    g_webSocket.onerror = function(message) {
        addLineToChatBox("Error!");
    };
}
 
/* ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œ */
function addLineToChatBox(_line) {
    if (_line == null) {
        _line = "";
    }
    
    var chatBoxArea = document.getElementById("chatBoxArea");
    chatBoxArea.value += _line + "\n";
    chatBoxArea.scrollTop = chatBoxArea.scrollHeight;    
}
 
/* Send ๋ฒ„ํŠผ ํด๋ฆญํ•˜๋ฉด ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€ ์ „์†ก */
function sendButton_onclick() {
    var inputMsgBox = document.getElementById("inputMsgBox"); // $('#inputMsgBox').val();
    if (inputMsgBox == null || inputMsgBox.value == null || inputMsgBox.value.length == 0) {
        return false;
    }
    
    var chatBoxArea = document.getElementById("chatBoxArea");
    
    if (g_webSocket == null || g_webSocket.readyState == 3) {
        chatBoxArea.value += "Server is disconnected.\n";
        return false;
    }
    
    // ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€ ์ „์†ก
    g_webSocket.send('['+ userid +'] ' + inputMsgBox.value);
    inputMsgBox.value = "";
    inputMsgBox.focus();
    
    return true;
}
 
/* Disconnect ๋ฒ„ํŠผ ํด๋ฆญํ•˜๋Š” ๊ฒฝ์šฐ ํ˜ธ์ถœ */
function disconnectButton_onclick() {
    if (g_webSocket != null) {
        g_webSocket.close();    
    }
}
 
/* inputMsgBox ํ‚ค ์ž…๋ ฅํ•˜๋Š” ๊ฒฝ์šฐ ํ˜ธ์ถœ */
function inputMsgBox_onkeypress() {
    if (event == null) {
        return false;
    }
    
    // ์—”ํ„ฐํ‚ค ๋ˆ„๋ฅผ ๊ฒฝ์šฐ ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€ ์ „์†ก
    var keyCode = event.keyCode || event.which;
    if (keyCode == 13) {
        sendButton_onclick();
    }
}
</script>
</head>
<body>
    <input id="inputMsgBox" style="width: 250px;" type="text" onkeypress="inputMsgBox_onkeypress()">
    <input id="sendButton" value="Send" type="button" onclick="sendButton_onclick()">
    <input id="disconnectButton" value="Disconnect" type="button" onclick="disconnectButton_onclick()">
    <br/>
    <textarea id="chatBoxArea" style="width: 100%;" rows="10" cols="50" readonly="readonly"></textarea>
</body>
</html>
cs

 

 

 

 

 


 

โ—โ—ํŠน์ • ์ธ๋ฌผ๋งŒ ์ง€์ •ํ•˜์—ฌ ํ•ด๋‹น ์ƒ๋Œ€๋ฐฉ์—๊ฒŒ๋งŒ ๋ฉ”์„ธ์ง€ ๋ณด๋‚ด๊ธฐโ—โ—

 

WebSocketHandler.java , WSChatController.java , WebSocketConfiguration.java  ์œ„์— ์ฝ”๋“œ์™€ ๊ฐ™๋‹ค.

 

 

 

WebSocketHandler.java

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import java.util.*;
import java.util.Map.Entry;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
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 jakarta.servlet.http.HttpSession;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import lombok.extern.slf4j.Slf4j;
 
@Slf4j
public class WebSocketHandler extends TextWebSocketHandler {
    //private final List<WebSocketSession> webSocketSessions = new ArrayList<>();
    private static Map<String, WebSocketSession> userMap = new HashMap<>();
 
    @Override /* ํด๋ผ์ด์–ธํŠธ ์ ‘์†์‹œ์— ํ˜ธ์ถœ๋จ */
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //webSocketSessions.add(session);
        System.out.println("Client Connected");
 
        // ์ธํ„ฐ์…‰ํ„ฐ์— ์˜ํ•ด HttpSession์˜ ์†์„ฑ์€ ์•„๋ž˜์ฒ˜๋Ÿผ WebSocketSession๊ฐ์ฒด๋กœ ์ „๋‹ฌ๋˜์–ด ์—ฌ๊ธฐ์„œ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค
        HttpSession httpSession = (HttpSession) session.getAttributes().get("httpSession");
        log.info("์›น์†Œ์ผ“ํ•ธ๋“ค๋Ÿฌ, httpSession={}", httpSession.getId()); // ์ปจํŠธ๋กค๋Ÿฌ์˜ ์„ธ์…˜id์™€ ๋™์ผํ•œ์ง€ ํ™•์ธ
        String userid = (String) httpSession.getAttribute("userid");
        log.info("์›น์†Œ์ผ“ํ•ธ๋“ค๋Ÿฌ, userid={}", userid);
        userMap.put(userid, session);
    }
 
    @Override /* ์„œ๋ฒ„์— ๋ฉ”์‹œ์ง€ ๋„์ฐฉ์‹œ ํ˜ธ์ถœ๋จ */
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        System.out.println("Text Message:" + message.getPayload());
        JSONParser parser = new JSONParser(); // JSON-Simple ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ
        JSONObject jsObj = (JSONObject) parser.parse(message.getPayload().toString());
        String sender = (String) jsObj.get("sender");
        String receiver = (String) jsObj.get("receiver");
        WebSocketSession sess = userMap.get(receiver);
        /*for (WebSocketSession webSocketSession : webSocketSessions) {
         webSocketSession.sendMessage(message);
        }*/
        sess.sendMessage(message);
    }
 
    @Override /* ์ ‘์† ํ•ด์ œ์‹œ ํ˜ธ์ถœ๋จ */
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println("Connection Closed");
        String findUserid = "";
        for (Entry<String, WebSocketSession> entry : userMap.entrySet()) {
            if (entry.getValue()==session) { // ํ‚ค๊ฐ€ null์ด๋ฉด NullPointerException ์˜ˆ์™ธ ๋ฐœ์ƒ
                findUserid = entry.getKey();
                userMap.remove(findUserid);
                break;
            }
        }
    }
 
    @Override /* ์˜ค๋ฅ˜ ๋ฐœ์ƒ์‹œ ํ˜ธ์ถœ๋จ */
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println("Error:" + exception);
        super.handleTransportError(session, exception);
    }
 
}
cs

 

 

 

chat.html

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>์›น์†Œ์ผ“ ํ…Œ์ŠคํŠธ ํŽ˜์ด์ง€</title>
<script type="text/javascript">
 
var userid = '[[${userid}]]';
alert('userid=' + userid);
 
var g_webSocket = null;
window.onload = function() {
    host = "localhost";   /* ๋ฐฐํฌ์‹œ์— ํ˜ธ์ŠคํŠธ ์ฃผ์†Œ๋กœ ๋ณ€๊ฒฝ */
   //host = "localhost 192.168.0.94";
    g_webSocket = new WebSocket("ws://"+host+"/ws/chat");
    
    
    /* ์›น์†Œ์ผ“ ์ ‘์† ์„ฑ๊ณต์‹œ ์‹คํ–‰ */
    g_webSocket.onopen = function(message) {
        addLineToChatBox("Server is connected.");
    };
    
    
    /* ์›น์†Œ์ผ“ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹ ์‹œ ์‹คํ–‰ */
    g_webSocket.onmessage = function(message) {
        var jsObj = JSON.parse(message.data);
        
        addLineToChatBox('[' + jsObj.sender +'] ' + jsObj.msg);
    };
 
    /* ์›น์†Œ์ผ“ ์ด์šฉ์ž๊ฐ€ ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•˜๋Š” ๊ฒฝ์šฐ ์‹คํ–‰ */
    g_webSocket.onclose = function(message) {
        addLineToChatBox("Server is disconnected.");
    };
 
    /* ์›น์†Œ์ผ“ ์—๋Ÿฌ ๋ฐœ์ƒ์‹œ ์‹คํ–‰ */
    g_webSocket.onerror = function(message) {
        addLineToChatBox("Error!");
    };
}
 
/* ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œ */
function addLineToChatBox(_line) {
    if (_line == null) {
        _line = "";
    }
    
    var chatBoxArea = document.getElementById("chatBoxArea");
    chatBoxArea.value += _line + "\n";
    chatBoxArea.scrollTop = chatBoxArea.scrollHeight;    
}
 
/* Send ๋ฒ„ํŠผ ํด๋ฆญํ•˜๋ฉด ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€ ์ „์†ก */
function sendButton_onclick() {
    var inputMsgBox = document.getElementById("inputMsgBox"); // $('#inputMsgBox').val();
    if (inputMsgBox == null || inputMsgBox.value == null || inputMsgBox.value.length == 0) {
        return false;
    }
    
    var chatBoxArea = document.getElementById("chatBoxArea");
    
    if (g_webSocket == null || g_webSocket.readyState == 3) {
        chatBoxArea.value += "Server is disconnected.\n";
        return false;
    }
    
    // ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€ ์ „์†ก
    //g_webSocket.send('['+ userid +'] ' + inputMsgBox.value);
    //inputMsgBox.value = "";
   // inputMsgBox.focus();
    
    var jsObj = {};
    jsObj.sender = userid;
    jsObj.receiver = 'jone';
    jsObj.msg = inputMsgBox.value;
    
    var jsStr = JSON.stringify(jsObj);
    g_webSocket.send(jsStr);
    
    inputMsgBox.value = "";
    inputMsgBox.focus();
    
    return true;
}
 
/* Disconnect ๋ฒ„ํŠผ ํด๋ฆญํ•˜๋Š” ๊ฒฝ์šฐ ํ˜ธ์ถœ */
function disconnectButton_onclick() {
    if (g_webSocket != null) {
        g_webSocket.close();    
    }
}
 
/* inputMsgBox ํ‚ค ์ž…๋ ฅํ•˜๋Š” ๊ฒฝ์šฐ ํ˜ธ์ถœ */
function inputMsgBox_onkeypress() {
    if (event == null) {
        return false;
    }
    
    // ์—”ํ„ฐํ‚ค ๋ˆ„๋ฅผ ๊ฒฝ์šฐ ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€ ์ „์†ก
    var keyCode = event.keyCode || event.which;
    if (keyCode == 13) {
        sendButton_onclick();
    }
}
</script>
</head>
<body>
    <input id="inputMsgBox" style="width: 250px;" type="text" onkeypress="inputMsgBox_onkeypress()">
    <input id="sendButton" value="Send" type="button" onclick="sendButton_onclick()">
    <input id="disconnectButton" value="Disconnect" type="button" onclick="disconnectButton_onclick()">
    <br/>
    <textarea id="chatBoxArea" style="width: 100%;" rows="10" cols="50" readonly="readonly"></textarea>
</body>
</html>
cs

 

 

์‹คํ–‰๊ฒฐ๊ณผ :

(23.01.02)Spring ํ”„๋ ˆ์ž„์›Œํฌ: ์›น์†Œ์ผ“์„ ์ด์šฉํ•œ ์ฑ„ํŒ…ํ”„๋กœ๊ทธ๋žจ ๋งŒ๋“ค๊ธฐ - undefined - โ—โ—ํŠน์ • ์ธ๋ฌผ๋งŒ ์ง€์ •ํ•˜์—ฌ ํ•ด๋‹น ์ƒ๋Œ€๋ฐฉ์—๊ฒŒ๋งŒ ๋ฉ”์„ธ์ง€ ๋ณด๋‚ด๊ธฐโ—โ—

 

(23.01.02)Spring ํ”„๋ ˆ์ž„์›Œํฌ: ์›น์†Œ์ผ“์„ ์ด์šฉํ•œ ์ฑ„ํŒ…ํ”„๋กœ๊ทธ๋žจ ๋งŒ๋“ค๊ธฐ - undefined - โ—โ—ํŠน์ • ์ธ๋ฌผ๋งŒ ์ง€์ •ํ•˜์—ฌ ํ•ด๋‹น ์ƒ๋Œ€๋ฐฉ์—๊ฒŒ๋งŒ ๋ฉ”์„ธ์ง€ ๋ณด๋‚ด๊ธฐโ—โ—

์ˆ˜์‹ ์ž๋กœ ์ง€์ •ํ•ด๋‘” jone ๋งŒ ๋ฉ”์„ธ์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

(23.01.02)Spring ํ”„๋ ˆ์ž„์›Œํฌ: ์›น์†Œ์ผ“์„ ์ด์šฉํ•œ ์ฑ„ํŒ…ํ”„๋กœ๊ทธ๋žจ ๋งŒ๋“ค๊ธฐ - undefined - โ—โ—ํŠน์ • ์ธ๋ฌผ๋งŒ ์ง€์ •ํ•˜์—ฌ ํ•ด๋‹น ์ƒ๋Œ€๋ฐฉ์—๊ฒŒ๋งŒ ๋ฉ”์„ธ์ง€ ๋ณด๋‚ด๊ธฐโ—โ—

 

 ๋ชจ๋“  ์ฑ„ํŒ… ์ ‘์†์ž ๋ฆฌ์ŠคํŠธ ๊ตฌํ•˜๊ธฐ
    - ์ฑ„ํŒ…์— ์ ‘์†ํ•˜๋Š” ๋ชจ๋“  ์ด์šฉ์ž์˜ ๋ฆฌ์ŠคํŠธ ์ž‘์„ฑ
    - ํ•œ ์ด์šฉ์ž๊ฐ€ ๋ชจ๋“  ์ด์šฉ์ž์˜ ์•„์ด๋””๋ฅผ ๊ตฌํ•˜๋ ค๋ฉด...
    - ๋ˆ„๊ตฌ๋‚˜ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์˜์—ญ์— ์ ‘์†์ž ๋ชฉ๋ก์„ ์œ ์ง€
    - ์ ‘์†์ž๊ฐ€ ์ด์šฉ์ž ๋ชฉ๋ก์„ ์š”์ฒญํ•  ๋•Œ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๊ทธ ์˜์—ญ์— ์ ‘์†
    - ์ ‘์†์ž ๋ชฉ๋ก์„ JSON ๋ฐฐ์—ด ํ˜•์‹์œผ๋กœ ์‘๋‹ต
    - application ์˜์—ญ(Scope)์— ๋ชจ๋“  ์ ‘์†์ž์˜ ID๋ฅผ ๊ธฐ๋กํ•œ๋‹ค
    - ServletContext ctx = request.getServletContext();
    - ctx.setAttribute("key", "value");
    - ctx.setAttribute("allids", "value");  // list, set, map
   Set<String> set = new HashSet<>();
   ctx.setAttribute("allids", set);

   set = ctx.getAttribute("allids");
   set.add("์ ‘์†์ž ID");

   @GetMapping("/allids")
   @ResponseBody
   public Map<String, List<String>> getAllIds(HttpServletRequest request)
   {
       Set<String> set = (Set<String>)request.getServletContext().getAttribute("allids");
       // set์œผ๋กœ๋ถ€ํ„ฐ ์•„์ด๋””๋ฅผ ๊บผ๋‚ด์„œ ๋ฆฌ์ŠคํŠธ์— ๋‹ด๋Š”๋‹ค
       // ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งต์— ์ €์žฅ
       // ๋งต์„ ๋ฆฌํ„ด
   }

   ์›น์†Œ์ผ“ ์ ‘์†์‹œ
    - ServletContext ์— userid ์ €์žฅ
    - ์›น์†Œ์ผ“ ํ•ธ๋“ค๋Ÿฌ์—์„œ๋„ ServletContext์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ด์•ผ ํ•จ
    - ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ํ†ตํ•ด์„œ ServletContext๋ฅผ ๊ตฌํ•ด์„œ attributes.put("ctx", ctx ์ฐธ์กฐ๋ณ€์ˆ˜);

   ์›น์†Œ์ผ“ ํ•ธ๋“ค๋Ÿฌ์—์„œ...
   ServletContext ctx = (ServletContext)attributes.get.....get("ctx");

 

๋ชจ๋“  ์ด์šฉ์ž์—๊ฒŒ ์ ‘์†์ž ๋ชฉ๋ก ๋ณด๋‚ด๊ธฐ
   WebSocketHandler, afterConnectionEstablished ๋ฉ”์†Œ๋“œ์— ์•„๋ž˜์˜ ๋‚ด์šฉ ์ถ”๊ฐ€
   /* ๋ชจ๋“  ์ด์šฉ์ž์—๊ฒŒ ์ด์šฉ์ž ๋ชฉ๋ก์„ JSON๋ฌธ์ž์—ด๋กœ ์ „์†กํ•œ๋‹ค */
   Set<String> set = userMap.keySet();
   JSONArray jsArr = new JSONArray();
   Iterator<String> it = set.iterator();
   while(it.hasNext())
   {
      String uid = it.next();
      jsArr.add(uid);
   }
   JSONObject jsObj = new JSONObject();
   jsObj.put("allids", jsArr);
   String jsStr = jsObj.toJSONString();
   session.sendMessage(new TextMessage(jsStr));


   

๋Œ“๊ธ€