보동이용용 2023. 5. 8. 21:11
반응형

HTTP 프로토콜의 conectless구조에의해서 stateless특성이 생김. stateless를 극복하기 위한 scope.

이 구조를 극복하기위해 connectfull방식 이용함. (connection을 수립하고 끊을 때가 의도적으로 되게끔 한다.)

 TCP 3-way Handshake

수시로 F5새로운 요청을 발생시켜야 커넥션을 연결할 수 있다. 이 문제를 해결하기위해 WEB SOCKET이 있다.

이 전의 방식이 있다. HTTP 1.0시절에는 웹소켓이 없었다. 그래서 인터벌 설정을 해놓고 일정한 주기로 서버에 연결을 수립하여 데이터를 갱신받았다. Long Polling구조 . 여러명이 하면 부하를 감당하기 힘들다. 그래서 web Socket으로 사용하여 커넥트풀방식을 사용하게 된다.

커넥트레스 : 의도적이지 않은 연결의 이음과 끊음

커넥트풀 : 의도적으로 연결하고 끊음.

https://socketsbay.com/test-websockets

 

WebSockets - 👩‍💻 Do tests for FREE 💪 - SocketsBay.com

SocketsBay.com: WebSockets - Do tests. 👨🏽Free test. 👍🏻 Flexibility - We can adjust to different situations. 🌇 Incredibly-fast websites. 🥇

socketsbay.com

100번대 상태코드

연결이 끊이지 않았다. time 이 pending

wss 서버(시큐어서버)?

 

1. 클라이언트 사이드 자바스크립트 유아이 작성(이 사이트 주소 이용해서 그대로 해보자.) 

 

<mvc:view-controller path="/websocket/sample1" view-name="websocket/sample1"/>

서블릿컨텍스트에 추가

<definition name="websocket/*" extends="parent">
   <put-attribute name="body" value="/WEB-INF/jsp/websocket/{1}.jsp" />
  </definition>

타일즈 설정파일에 추가

<security:intercept-url pattern="/websocket/**" access="permitAll"/>

시큐리티컨텍스트 추가

 

jsp 만들고실행

콘솔에 let ws = new WebSocket("wss://socketsbay.com/wss/v2/1/demo/") 웹소켓 객체 생성

웹소켓은 기본생성자가 없다. 웹소켓을 받을 서버가 필요함. 아까 그 주소의 서버를 넣어봄.

 

on : 이벤트 핸들러

onopen 연결 잇기 핸들러

onclose 연결 끊기 핸들러

onerror 연결 오류 

 

<script>
let ws = new WebSocket("wss://socketsbay.com/wss/v2/1/demo/");
ws.onopen=function(event){
console.log(event);
}
ws.onclose=function(event){
console.log(event);
}
ws.onmessage=function(event){
console.log(event);
}
}
</script>

event의 타겟은 웹소켓

에코사이트에서 보낸 메세지가 우리 어플리케이션에서 돌아간다.

이 데이타 프로퍼티가 내용을 담당.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h4> 웹소켓 샘플 </h4>
<button class="wsControl" data-role="connect">연결수립</button>
<button class="wsControl" data-role="disconnect" disabled="disabled">연결종료</button>
<div id = "messageArea">

</div>
<script>
	const messageArea = $("#messageArea");
	let ws = null;
	const wsControl = $(".wsControl").on("click", function(event){
		//html element의 데이터 속성 접근방법 dataset => map이다.
		switch (this.dataset.role) {
		case "connect":
			ws = connectWS();
			break;

		default:
			ws.close(1000); // 연결끊음. 정상종료시 종료코드 1000
			break;
		}
	});
	
	function connectWS(){
		let ws = new WebSocket("wss://socketsbay.com/wss/v2/1/demo/");
		ws.onopen=function(event){
			console.log(event);	
			messageArea.append($("<p>").html("Connect!"));
			// 문자열로 관리 attr, 값을 그대로 가지고 놀거다 prop
			wsControl.prop("disabled", (i,v)=>!v); //!v로 disabled속성을 토글링할수있다.
		}
		ws.onclose=function(event){
			console.log(event);	
			messageArea.append($("<p>").html("DisConnect!"));
			wsControl.prop("disabled", (i,v)=>!v); //!v로 disabled속성을 토글링할수있다.
		}
		ws.onmessage=function(event){
			console.log(event);	
			messageArea.append($("<p>").html(event.data));
		}
		return ws;
	}
</script>

--------------------------------------

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>${org.springframework-version}</version>
</dependency>

추가

--------------------------------------

웹 소켓은 웹에 종속되어야하는 것. 그러니 하위컨테이너에 등록.

<param-value>
      /WEB-INF/spring/servlet-context.xml
      /WEB-INF/spring/websocket-context.xml
</param-value>

web.xml추가

 

public class SampleEchoWebSocketHandler extends TextWebSocketHandler

컨트롤러에서 TextWebSocketHandler이거를 상속받아.

 

<bean id="sampleEchoWebSocketHandler" class="kr.or.ddit.websocket.handler.SampleEchoWebSocketHandler"></bean>
<websocket:handlers>
<websocket:mapping handler="sampleEchoWebSocketHandler" path="/ws/echo"/>
</websocket:handlers>

빈으로 등록하고 상속받은 핸들러 등

2. 소켓 연결을 실제로 해줄 서버가 필요함

 

package kr.or.ddit.websocket.handler;

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 lombok.extern.slf4j.Slf4j;

@Slf4j
public class SampleEchoWebSocketHandler extends TextWebSocketHandler {
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		// 클라이언트사이드로치면 onopen // super에서 하는일은 없음. // session 통로의미
		log.info("연결 수립 : {}", session);
	}
	
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		// 클라이언트사이드로치면 onclose
		log.info("연결 종료 : {}", session);
	}
	
	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		// 클라이언트사이드로치면 onerror => exception이 하나 들어와있다.
		log.error(exception.getMessage(), exception);
	}
	
	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		// 클라이언트사이드로치면 onmessage => bainaryMessage는 파일도 전송가능하다.
		String realMsg = message.getPayload();
		session.sendMessage(new TextMessage(realMsg)); // session.sendMessage(message);
		
	}
}

 

웹소켓은 형식이 없어서 sender에 대한 형식을 우리가 결정해주어야한다.

 

반응형