no image
SockJS 간단한 공부(SockJS는 이제 필요없는가?)
개요 Spring Documentation에서 WebSocket API를 공부한 뒤 다음 단계는 SockJS 였습니다. SockJS를 간단히 공부해보았는데요. 공부해봤을 때, 'SockJS가 필요없는건가?'라는 생각이 들어 블로그 글을 정리해봤습니다. 만약 SockJS에 대해 자세히 알아보고 싶으신 분은 아래의 블로그를 참조해주시길 부탁드립니다. [Spring Boot] WebSocket과 채팅 (2) - SockJS [Spring Boot] WebSocket과 채팅 (1) 일전에 WebSocket(웹소켓)과 SockJS를 사용해 Spring 프레임워크 환경에서 간단한 하나의 채팅방을 구현해본 적이 있다. [Spring MVC] Web Socket(웹 소켓)과 Chatting(채팅) 기존 공 dev-go..
2023.10.18
no image
WebSocket API를 사용해 채팅창 구현하기
코드는 아래의 깃허브 주소에서 WebSocketAPIToy 폴더 속에 있습니다. https://github.com/Dev-Taehee/WebSocketToy 설정 저는 Spring Initializr를 활용하여 위와 같이 설정한 후 시작했습니다. 개요 WebSocket API의 가장 중요한 두 가지는 WebSocketHandler와 WebSocketConfigurer 입니다. public class MyHandler extends TextWebSocketHandler { @Override public void handleTextMessage(WebSocketSession session, TextMessage message) { // ... } } WebSocketHandler는 말그대로 WebSocket..
2023.10.10
no image
AJAX, HTTP Streaming, Long Polling 이란?
개요 웹소켓 공부를 시작하며 본 Spring Documentation에는 다음과 같은 구문이 있었습니다. '그러나 AJAX, HTTP Streaming 또는 Long Polling을 결합하면 간단하고 효과적인 제공할 수 있습니다. 예를 들어 뉴스, 메일, 소셜 피드는 동적으로 업데이트되어야 하지만 몇 분마다 업데이트해도 괜찮습니다. 또한 메시지의 양이 상대적으로 적은 경우에도 포함됩니다.' 웹소켓 공부를 시작하기 전에 대체재로 사용 가능한 AJAX, HTTP Streaming, Long Polling에 대해 간단히 파악하고 싶어 살짝 공부해보고 넘어가보려고합니다. AJAX란? AJAX란 Asynchronous JavaScript and XML의 약자입니다. AJAX는 빠르게 동작하는 동적인 웹 페이지를 ..
2023.09.22
no image
웹소켓 공부를 시작하며
개요 게임동아리 멤버들과 주말에 내전을 즐기며 가끔 칼바람나락 내전을 즐길 때가 있었습니다. 롤 게임에서 사용자 설정 방을 만들면 아쉬운 점이 칼바람나락의 주사위 기능이 없다는 점이었습니다. 그래서 랜덤 팀 나누기 디스코드 봇을 만들던 때와 비슷하게 프로젝트로 개발하려고 생각했었는데요. 한 웹 페이지에 10명의 인원이 상호작용이 가능하려면 웹소켓을 이용해야한다는 점을 알게되었습니다. 이에 저는 웹소켓에 대해 공부해보고 사용해보려 합니다. 아래의 Spring Documentation을 참고하여 진행하려고 합니다. WebSockets :: Spring Framework The WebSocket protocol, RFC 6455, provides a standardized way to establish a f..
2023.09.21

목차

    개요

    Spring Documentation에서 WebSocket API를 공부한 뒤 다음 단계는 SockJS 였습니다. SockJS를 간단히 공부해보았는데요. 공부해봤을 때, 'SockJS가 필요없는건가?'라는 생각이 들어 블로그 글을 정리해봤습니다. 만약 SockJS에 대해 자세히 알아보고 싶으신 분은 아래의 블로그를 참조해주시길 부탁드립니다.

     

    [Spring Boot] WebSocket과 채팅 (2) - SockJS

    [Spring Boot] WebSocket과 채팅 (1) 일전에 WebSocket(웹소켓)과 SockJS를 사용해 Spring 프레임워크 환경에서 간단한 하나의 채팅방을 구현해본 적이 있다. [Spring MVC] Web Socket(웹 소켓)과 Chatting(채팅) 기존 공

    dev-gorany.tistory.com

     

    SockJS란?

    SockJS는 애플리케이션이 WebSocket API를 사용할 때, 만약 브라우저가 WebSocket을 받아들이지 못하는 상태라면 애플리케이션 코드 변경 없이 런타임에서 대안을 실행하기 위한 것입니다.

     

    https://github.com/sockjs/sockjs-client/

    위 그림에서 처럼 각 브라우저의 버전에 따라 WebSocket을 지원하지 않는 경우가 있습니다. 또한 Server, Client 중간에 위치한 Proxy가 Upgrade Header를 해석하지 못해 서버에 전달하지 못할 수 있습니다. 마지막으로 Server, Client 중간에 위치한 Proxy가 유휴 상태에서 도중에 Connection을 종료시킬 수도 있습니다.

     

    이런 상황에 사용하는 것이 WebSocket Emulation입니다. WebSocket Emulation은 우선 WebSocketㅇ르 시도하고 실패할 경우 HTTP Streamin, Long Polling과 같은 HTTP 기반의 다른 기술로 전환해 다시 연결을 시도하는 것을 뜻합니다.

     

    Spring을 사용하기에 SockJS를 사용합니다.

    (Node.js는 Socket.io라는 것을 사용한다고 합니다. SockJS-node를 사용해도 될 것 같네요.)

     

    필요없다고 생각하는 이유

    브라우저 버전의 고도화

    공부하다보니 SockJS를 사용해야하는가에 대한 의문이 들었습니다. SockJS를 사용하는 대표적인 이유가 WebSocket을 지원하지 않는 브라우저를 사용하는 경우이기 때문인데요. 대표적으로 IE 버전 10미만의 인터넷 익스플로러가 지원이 되지 않습니다. 하지만 마이크로소프트 공식 홈페이지에는 인터넷 익스플로러에 대한 지원이 2022년 6월 15일에 종료되었다고 하더군요. 또한 Firefox 인터넷도 자동 업데이트를 하도록 설정되어있다고 하기에 웬만한 브라우저는 다 지원되지 않을까라는 생각을 했습니다.

    https://support.microsoft.com/ko-kr/windows/internet-explorer-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C%ED%95%98%EA%B8%B0-d49e1f0d-571c-9a7b-d97e-be248806ca70#ID0EBBD=Windows_10

    프록시 서버의 웹소켓 지원

    두 번째로 SockJS를 사용해야하는 이유는 프록시 상황에서 웹소켓을 사용하기 어렵다는 이야기를 들었기 때문입니다. 하지만 찾아보니 Nginx의 경우에는 버전 1.3부터 WebSocket을 지원하며 WebSocket의 로드밸런싱을 수행할 수 있다고 합니다. 

     

    결론

    SockJS에 대해 간단히 알아보고 필요없다고 생각한 이유에 대해서도 알아봤습니다. 혹시 최근에도 SockJS를 이용하여 작업하시는 분이 계시다면 어느 상황에서 사용되는지 알려주시면 대단히 감사드리겠습니다.

     

     

    reference

    https://docs.spring.io/spring-framework/reference/web/websocket/fallback.html

    https://github.com/sockjs/sockjs-client/

    https://dev-gorany.tistory.com/224

    https://hyeon9mak.github.io/nginx-web-socket-proxy-configuration/

     

    목차

      코드는 아래의 깃허브 주소에서 WebSocketAPIToy 폴더 속에 있습니다.

      https://github.com/Dev-Taehee/WebSocketToy

      설정

      https://start.spring.io/

      저는 Spring Initializr를 활용하여 위와 같이 설정한 후 시작했습니다.

       

      개요

      WebSocket API의 가장 중요한 두 가지는 WebSocketHandler와 WebSocketConfigurer 입니다.

      public class MyHandler extends TextWebSocketHandler {
      
      	@Override
      	public void handleTextMessage(WebSocketSession session, TextMessage message) {
      		// ...
      	}
      
      }

      WebSocketHandler는 말그대로 WebSocket을 다루는 친구입니다. WebSocket을 통해 오는 message들을 처리할 수도 있고 WebSocket이 연결된 후의 행동이나 WebSocket이 종료된 후의 행동을 관리할 수 있습니다.

      @Configuration
      @EnableWebSocket
      public class WebSocketConfig implements WebSocketConfigurer {
      
      	@Override
      	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
      		registry.addHandler(myHandler(), "/myHandler");
      	}
      
      	@Bean
      	public WebSocketHandler myHandler() {
      		return new MyHandler();
      	}
      
      }

      WebSocketConfigurer는 WebSocket과 관련된 설정들을 관리할 수 있게 해줍니다. WebSocketHandler를 등록해주는 것과 등록된 WebSocketHandler에 접속할 수 있는 URL을 구체적으로 정해주는 등의 작업을 할 수 있습니다.

       

      만약 기본 설정인 Tomcat이 아닌 Jetty를 사용해주는 경우에는 아래와 같이 WebSocketServerFactory를 이용하여 사전 설정을 진행해주어야 한다고 합니다.

      @Configuration
      @EnableWebSocket
      public class WebSocketConfig implements WebSocketConfigurer {
      
      	@Override
      	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
      		registry.addHandler(echoWebSocketHandler(),
      			"/echo").setHandshakeHandler(handshakeHandler());
      	}
      
      	@Bean
      	public DefaultHandshakeHandler handshakeHandler() {
      
      		WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
      		policy.setInputBufferSize(8192);
      		policy.setIdleTimeout(600000);
      
      		return new DefaultHandshakeHandler(
      				new JettyRequestUpgradeStrategy(new WebSocketServerFactory(policy)));
      	}
      
      }

      단순히 Handler와 Configurer 두 가지를 상속받은 후 구현하면 WebSocket 연결이 완료된다고 하니 굉장히 편리한 것 같습니다. 저는 두 클래스를 이용하여 채팅창을 구현해보는 실습을 통해 이해도를 높여보려고합니다.

       

      실습

      websocket 설정

      websocket 설정을 위하여 앞서 말씀드린 Handler와 Configurer 2가지를 생성합니다.

      우선 Handler입니다.

      @Log4j2
      public class MyHandler extends TextWebSocketHandler {
      
          private static List<WebSocketSession> list = new ArrayList<>();
      
          @Override
          protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
              log.info("HandleTextMessage 진입");
              log.info("session: " + session);
              log.info("message: " + message);
              for(WebSocketSession webSocketSession : list) {
                  webSocketSession.sendMessage(message);
              }
          }
      
          @Override
          public void afterConnectionEstablished(WebSocketSession session) throws Exception {
              log.info(session + "클라이언트 접속");
              list.add(session);
          }
      }

      afterConnectionEstablished 메서드는 클라이언트가 접속하면 실행되는 메서드입니다.

      이를 통해 클라이언트가 채팅창에 들어오면 해당 클라이언트의 WebSocketSession을 등록해주는 작업을 진행하도록 하였습니다.

      handleTextMessage는 클라이언트가 텍스트 메시지를 보내면 해당 메시지를 채팅창에 참여한 사람들에게 보내주는 역할을 합니다.

       

      다음은 Configurer입니다.

      @Configuration
      @EnableWebSocket
      public class WebSocketConfig implements WebSocketConfigurer {
          @Override
          public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
              registry.addHandler(myHandler(), "ws/myHandler")
                      .setAllowedOrigins("*");
          }
      
          @Bean
          public WebSocketHandler myHandler() {
              return new MyHandler();
          }
      
      }

      Configurer는 앞선 예제 코드와 크게 변한 것이 없습니다.

      우선 Handler에 접속할 수 있는 url을 "ws/myHandler"로 사용했습니다.

      웹소켓을 이용하면 통신이 http 통신에서 Upgrade 헤더를 사용해 ws 통신으로 바뀌는 것을 앞선 시간에 확인할 수 있었습니다. 그런 이유로 "ws/myHandler"로 url을 정해봤습니다.

      setAllowedOrigins를 모두 허락해두었습니다.

       

      채팅창 접속 가능한 ChatController 생성

      채팅창에 접속 가능하도록 ChatController를 생성했습니다.

      @Controller
      public class ChatController {
      
          @GetMapping("/myHandler")
          public String getChat() {
              return "chat";
          }
      
      }

      endpoint를 "/myHandler"로 설정하고 접속시 chat.html을 열도록 해두었습니다.

       

      프론트엔드 구성

      프론트엔드 구성은 chatGPT로 작성한 후 제가 수정하는 방식으로 작업했습니다.

      우선 chat.html 입니다.

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>채팅 창</title>
          <link rel="stylesheet" th:href="@{/css/styles.css}">
      </head>
      
      <body>
          <div class="input-container">
              <label for="username">유저 이름: </label>
              <input type="text" id="username" class="username-input" placeholder="유저 이름을 입력하세요...">
              <button onclick="saveUsername()" class="save-button">저장</button>
          </div>
          <div class="chat-box">
              <div class="chat-container" id="chat-container">
                  <!-- 메시지가 여기에 나타남 -->
              </div>
      
              <div class="input-container">
                  <input type="text" id="message-input" class="message-input" placeholder="메시지를 입력하세요...">
                  <button onclick="sendMessage()" class="send-button">전송</button>
              </div>
          </div>
      
          <script th:src="@{/js/script.js}"></script>
      </body>
      
      </html>

      다음은 styles.css 입니다.

      body {
          font-family: Arial, sans-serif;
          margin: 0;
          padding: 0;
          background-color: #f0f0f0;
      }
      
      .chat-box {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          height: 100vh;
      }
      
      .chat-container {
          width: 80%;
          max-width: 400px;
          margin: 0 auto;
          background-color: #fff;
          border-radius: 10px;
          box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
          overflow-y: auto;
          height: 400px;
          padding: 20px;
      }
      
      .message {
          margin-bottom: 10px;
          padding: 10px;
          border-radius: 10px;
          max-width: 70%;
      }
      
      .sender-message {
          background-color: #f3d6c6;
          align-self: flex-end;
      }
      
      .user-message {
          background-color: #ccc;
      }
      
      .input-container {
          display: flex;
          margin-top: 20px;
      }
      
      .message-input {
          flex: 1;
          max-width: 400px;
          padding: 10px;
          border-radius: 5px;
          border: 1px solid #ccc;
      }
      
      .send-button {
          margin-left: 10px;
          padding: 10px 20px;
          border: none;
          border-radius: 5px;
          background-color: #4caf50;
          color: white;
          cursor: pointer;
      }

       

      위의 HTML과 CSS를 합쳐 아래의 화면이 나오도록 구성하였습니다.

       

      다음은 script.js 입니다.

      // WebSocket 서버 주소
      const websocketUrl = 'ws://localhost:8080/ws/myHandler';
      
      // WebSocket 연결
      const socket = new WebSocket(websocketUrl);
      
      // 연결이 열렸을 때 실행되는 이벤트 핸들러
      socket.addEventListener('open', (event) => {
          console.log('WebSocket 연결이 열렸습니다.');
      });
      
      // 메시지를 받았을 때 실행되는 이벤트 핸들러
      socket.addEventListener('message', (event) => {
          // 서버로부터 받은 메시지를 화면에 표시
          const receivedMessage = JSON.parse(event.data);
          displayMessage(receivedMessage.sender, receivedMessage.content, false);
      });
      
      // 연결이 닫혔을 때 실행되는 이벤트 핸들러
      socket.addEventListener('close', (event) => {
          console.log('WebSocket 연결이 닫혔습니다.');
      });
      
      function sendMessage() {
          var messageInput = document.getElementById('message-input');
          var message = messageInput.value.trim();
          if (message === '') return;
      
          var username = localStorage.getItem('username');
      
          const chatMessage = {
              sender: username,
              content: message
          }
      
          // 메시지를 WebSocket을 통해 서버로 전송
          socket.send(JSON.stringify(chatMessage));
      
          // // 입력한 메시지를 화면에 표시 (옵션)
          // displayMessage(username, message, true);
      
          // 입력 칸 비우기
          messageInput.value = '';
      }
      
      // 화면에 메시지를 표시하는 함수 (옵션)
      function displayMessage(sender, message, isSender) {
          var chatContainer = document.getElementById('chat-container');
          var messageElement = document.createElement('div');
          messageElement.textContent = sender + ': ' + message;
          messageElement.classList.add('message');
      
          var username = localStorage.getItem('username');
      
          if (username === sender) {
              messageElement.classList.add('sender-message');
          } else {
              messageElement.classList.add('user-message');
          }
      
          chatContainer.appendChild(messageElement);
      
          // 최하단으로 스크롤
          chatContainer.scrollTop = chatContainer.scrollHeight;
      }
      
          // 로컬 스토리지에서 유저 이름을 불러오고 입력 필드에 채우는 함수
      function loadUsername() {
          var savedUsername = localStorage.getItem('username');
          if (savedUsername) {
              document.getElementById('username').value = savedUsername;
          }
      }
      
          // 유저 이름을 로컬 스토리지에 저장하는 함수
      function saveUsername() {
          var usernameInput = document.getElementById('username');
          var username = usernameInput.value.trim();
          if (username === '') return;
      
          localStorage.setItem('username', username);
          alert('유저 이름이 저장되었습니다: ' + username);
      }
      
      // 페이지 로드 시 유저 이름을 불러옴
      loadUsername();
      
      // 아래에 메시지 전송 함수 및 기타 함수들을 추가하면 됩니다.

       

      js 파일에서 볼 수 있듯이 앞서 WebSocket Configurer에서 설정한 주소인 ws/Handler로 연결을 요청하도록 되어 있습니다. 또한 웹소켓 연결이므로 http://가 아닌 ws:// 로 시작된다는 점을 확인하실 수 있습니다.

       

      앞선 작업들을 통해 다음과 같이 채팅창 기능이 구현되었습니다.

      목차

        개요

        웹소켓 공부를 시작하며 본 Spring Documentation에는 다음과 같은 구문이 있었습니다.

        '그러나 AJAX, HTTP Streaming 또는 Long Polling을 결합하면 간단하고 효과적인 제공할 수 있습니다. 예를 들어 뉴스, 메일, 소셜 피드는 동적으로 업데이트되어야 하지만 몇 분마다 업데이트해도 괜찮습니다. 또한 메시지의 양이 상대적으로 적은 경우에도 포함됩니다.'

        웹소켓 공부를 시작하기 전에 대체재로 사용 가능한 AJAX, HTTP Streaming, Long Polling에 대해 간단히 파악하고 싶어 살짝 공부해보고 넘어가보려고합니다.

         

        AJAX란?

        AJAX란 Asynchronous JavaScript and XML의 약자입니다.

        AJAX는 빠르게 동작하는 동적인 웹 페이지를 만들기 위한 개발 기법의 하나입니다.

         

        AJAX는 웹 페이지 전체를 다시 로딩하지 않고도, 웹페이지의 일부분만을 갱신할 수 있습니다.

        즉, AJAX를 이용하면 백그로운드 영역에서 서버와 통신하여, 그 결과를 웹 페이지의 일부분에만 표시할 수 있습니다.

         

        이때 서버와는 다음과 같은 다양한 형태의 데이터를 주고받을 수 있습니다.

        • JSON
        • XML
        • HTML
        • 텍스트 파일 등

         

        AJAX의 장점

        AJAX를 이용하면 다음과 같은 장점이 있습니다.

        1. 웹 페이지 전체를 다시 로딩하지 않고도, 웹페이지의 일부분만을 갱신할 수 있습니다.
        2. 웹 페이지가 로드된 후에 서버로 데이터 요청을 보낼 수 있습니다.
        3. 웹 페이지가 로드된 후에 서버로부터 데이터를 받을 수 있습니다.
        4. 백그라운드 영역에서 서버로 데이터를 보낼 수 있습니다.

         

        AJAX의 한계

        AJAX를 이용하면 여러 장점을 가지지만, AJAX로도 다음과 같은 일들을 처리할 수 없습니다.

        1. AJAX는 클라이언트가 서버에 데이터를 요청하는 클라이언트 풀링 방식을 사용하므로, 서버 푸시 방식의 실시간 서비스는 만들 수 없습니다.
        2. AJAX로는 바이너리 데이터를 보내거나 받을 수 없습니다.
        3. AJAX 스크립트가 포함된 서버가 아닌 다른 서버로 AJAX 요청을 보낼 수는 없습니다.
        4. 클라이언트의 PC로 AJAX 요청을 보낼 수는 없습니다.

        클라이언트 풀링(client pooling) 방식이란?

        사용자가 직접 원하는 정보를 서버에게 요청하여 얻는 방식을 의미합니다.

        이에 반해 서버 푸시(server push) 방식이란 사용자가 요청하지 않아도 서버가 알아서 자동으로 특정 정보를 제공하는 것을 의미합니다.

        스마트폰에서 각종 앱이 보내는 푸시 알림이 서버 후시 방식의 대표적인 예입니다.

         

        AJAX의 작동 원리 등 다양한 활용 방법에 대해 자세히 공부하고 싶으시면 아래의 글을 참고해주세요.

         

        코딩교육 티씨피스쿨

        4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

        tcpschool.com

         

        HTTP Streaming이란?

        HTTP Streaming은 HTTP 프로토콜을 사용하여 데이터를 조각조각으로 전송하는 방식으로 실시간 미디어 스트리밍, 실시간 웹 애플리케이션 및 다른 실시간 데이터 전송 시나리오에서 사용됩니다. 이것은 브라우저나 앱 클라이언트가 데이터를 조금씩 수신하고 화면에 표시하거나 처리할 수 있도록하는 기술입니다.

         

        HTTP Streaming의 장점

        HTTP Streaming을 사용하면 다음과 같은 장점이 있습니다.

        1. 미디어 스트리밍을 통해 사용자가 콘텐츠를 실시간으로 시청하거나 듣는 동안 데이터의 일부만 다운로드할 수 있기에 대역폭을 절약하고 사용자 경험을 향상시킬 수 있습니다.
        2. HTTP를 기반으로 하는 스트리밍은 다양한 플랫폼과 장치에서 지원되므로, 웹 브라우저, 모바일 앱, 스마트 TV 등 다양한 환경에서 사용할 수 있습니다.
        3. HTTP를 사용하면 콘텐츠를 캐싱하고 CDN(Content Delivery Network)을 통해 전송하여 콘텐츠 전송 성능을 최적화할 수 있습니다.

         

        HTTP Streaming의 한계

        HTTP Streaming에 많은 장점이 있지만 다음과 같은 한계점이 있습니다.

        1. HTTP Streaming에서 데이터는 조각으로 전송되므로 처음 몇 조각을 수신한 후에 재생이 시작될 수 있습니다. 이로 인해 초기 버퍼링 지연이 발생할 수 있습니다.
        2. HTTP Streaming은 본질적으로 데이터 전송에 대한 암호화 또는 보안 조치를 제공하지 않습니다. 추가 보안 계층이 없으면 채팅 애플리케이션을 통해 교환되는 정보는 무단 액세스에 취약할 수 있습니다.
        3. 다양한 스트리밍 프로토콜이 존재하기에 브라우저 및 장치에 따라 호환성에 문제가 발생할 수 있습니다.
        4. HTTP Streaming은 서버 및 클라이언트 측에서 추가 리소스를 사용하므로 서버에 대한 리소스가 집약적일 수 있습니다. 그렇기에 대규모 미디어 스트리밍 서비스의 경우 서버 인프라 및 대역폭 관리가 중요한 문제가 될 수 있습니다.

         

        HTTP Streaming에 대해 자세히 알아보고 싶으신 분은 아래 글을 참고해주세요.

         

        What is HTTP Streaming?

        Read the Real-time communication API Blog now.

        www.pubnub.com

         

         

        Long Polling 이란?

        Long Polling 방식은 클라이언트가 서버에 HTTP Request를 요청하면 서버는 대기하고 있다가 이벤트가 발생 시 응답을하고 클라이언트는 응답을 받자마자 다시 서버에 Request를 요청보내 실시간성을 살리는 방식입니다.

        https://www.educative.io/answers/what-is-http-long-polling

         

        Long Polling 장점

        데이터가 업데이트되면 그 즉시 클라이언트에게 응답을 보내고 전달받은 데이터를 처리하므로 실시간성이 아주 높습니다.

         

        Long Polling 단점

        다수의 클라이언트가 존재하여 동시에 이벤트가 발생할 경우, 서버는 각 클라이언트마다 응답을 해주어야하기 때문에 순간 서버의 부담이 증가하게 됩니다.

        또한 데이터가 주어지는 즉시 바로 반응하고 보내므로 요청 간격이 줄어든다면 polling보다 훨씬 데이터를 많이 보내게됩니다.

         

         

        reference

        https://velog.io/@hustle-dev/JavaScript-Long-Polling

        목차

          개요

          게임동아리 멤버들과 주말에 내전을 즐기며 가끔 칼바람나락 내전을 즐길 때가 있었습니다.

          롤 게임에서 사용자 설정 방을 만들면 아쉬운 점이 칼바람나락의 주사위 기능이 없다는 점이었습니다.

          그래서 랜덤 팀 나누기 디스코드 봇을 만들던 때와 비슷하게 프로젝트로 개발하려고 생각했었는데요.

          한 웹 페이지에 10명의 인원이 상호작용이 가능하려면 웹소켓을 이용해야한다는 점을 알게되었습니다.

          이에 저는 웹소켓에 대해 공부해보고 사용해보려 합니다.

          아래의 Spring Documentation을 참고하여 진행하려고 합니다.

           

           

          WebSockets :: Spring Framework

          The WebSocket protocol, RFC 6455, provides a standardized way to establish a full-duplex, two-way communication channel between client and server over a single TCP connection. It is a different TCP protocol from HTTP but is designed to work over HTTP, usin

          docs.spring.io

           

           

          Getting Started | Using WebSocket to build an interactive web application

          In Spring’s approach to working with STOMP messaging, STOMP messages can be routed to @Controller classes. For example, the GreetingController (from src/main/java/com/example/messagingstompwebsocket/GreetingController.java) is mapped to handle messages t

          spring.io

           

          웹소켓이란

          WebSocket 프로토콜인 RFC6455는 단일 TCP 연결을 통해 클라이언트와 서버 간에 전이중 양방향 통신 채널을 설정하는 표준화된 방법을 제공합니다. 이는 HTTP와 다른 TCP 프로토콜이지만 포트 80 및 443을 사용하고 기존 방화벽 규칙을 재사용할 수 있도록 HTTP를 통해 작동하도록 설계되있습니다.

           

          WebSocket 상호 작용은 HTTP Upgrade 헤더를 사용하여 업그레이드하거나 WebSocket 프로토콜로 전환하는 HTTP 요청으로 시작합니다. 다음 예에서는 이러한 상호 작용을 보여줍니다.

           

          1. Upgrade 헤더입니다.

          2. Upgrade 연결입니다.

           

          일반적인 200 상태 코드 대신 WebSocket을 지원하는 서버는 다음과 유사한 출력을 반환합니다.

          1. 프로토콜 스위치

           

          성공적인 핸드셰이크 후에는 HTTP 업그레이 요청의 기반이 되는 TCP 소켓이 클라이언트와 서버 모두에 대해 계속 열려 메시지를 계속 보내고 받을 수 있습니다.

           

          WebSocket 서버가 웹 서버(예: nginx) 뒤에서 실행 중인 경우 WebSocket 업그레이드 요청을 WebSocket 서버로 전달하도록 구성해야 할 수 있습니다. 클라우드 환경에서 실행되는 경우에도 마찬가지로 WebSocket 지원과 관련된 클라우드 제공업체의 지침을 확인해야합니다.

           

          Upgrade 헤더란

          HTTP 업그레이드는 클라이언트가 서버와 통신하기 위해 웹소켓과 같은 다른 프로토콜로 업그레이드를 요청할 수 있는 프로세스입니다.

           

          reference: https://runebook.dev/ko/docs/http/headers/upgrade

           

          https://www.geeksforgeeks.org/what-is-web-socket-and-how-it-is-different-from-the-http/

           

          HTTP와 WebSocket의 차이

          웹소켓 연결 HTTP 연결
          WebSocket은 설정된 연결 채널을 재사용하여 클라이언트에서  서버로 또는 서버에서 클라이언트로 데이털르 보낼 수 있는 양방향 통신 프로토콜입니다. 연결은 클라이언트나 서버에 의해 종료될 때까지 유지됩니다.
          (ws:// 또는 wss:// 시작합니다.)
          HTTP 프로토콜은 연결 지향 전송 계층 프로토콜인 TCP 프로토콜 위에서 작동하는 단방향 프로토콜입니다. HTTP 연결이 닫히면 응답을 받은 후 HTTP 요청 방법을 사용하여 연결을 생성할 수 있습니다.
          (http:// 또는 https:// 로 시작합니다.)
          상태코드 101을 통해 WebSocket의 전환 프로토콜을 나타냅니다. 상태코드 200을 통해 연결이 완료되었음을 나타냅니다.

           

          WebSocket을 사용해야 하는 경우

          거래, 모니터링, 알림 서비스와 같은 실시간 애플리케이션의 경우 WebSocket을 사용하여 단일 통신 채널에서 데이커를 수신하면 좋다고 합니다.

           

          이렇듯 WebSocket은 웹페이지를 동적이고 대화형으로 만들 수 있습니다. 그러나 AJAX, HTTP Streaming 또는 Long Polling을 결합하면 간단하고 효과적인 솔루션을 제공할 수 있습니다.

          예를 들어 뉴스, 메일, 소셜 피드는 동적으로 업데이트되어야 하지만 몇 분마다 업데이트해도 괜찮습니다. 또한 메시지의 양이 상대적으로 적은 경우에도 포함됩니다.

           

          WebSocket은 낮은 대기 시간, 높은 빈도 및 높은 볼륨의 조합의 경우에 큰 힘을 발휘합니다.

           

           

          Reference

          https://www.geeksforgeeks.org/what-is-web-socket-and-how-it-is-different-from-the-http/