이번 프로젝트에서 웹 소캣을 사용할 예정입니다. 프로젝트를 준비하는 기간동안 웹 소캣에 대해 공부하고 있습니다. 그 내용을 기록해두고자 합니다.
웹 소캣은 클라이언트와 서버간 메시지를 교환하기 위한 통신 방법 중 하나입니다. 비동기적으로 통신을 처리하여 효율적으로 실시간 양방향 통신을 구현하였습니다. 웹 소캣은 W3C와 IETF에 의해 표준으로 자리잡은 프로토콜이기 때문에, 현재 인터넷을 사용하는 환경에서 많이 사용됩니다.
실시간 통신이라는 특성 때문에 채팅, 주식, 비디오 등의 처리나, 여러 단말기(PC, 스마트폰)에 빠르게 데이터를 교환하는 실시간 처리가 필요한 부분에 사용됩니다.
웹 소캣 메시지는 텍스트 데이터나 바이너리 데이터를 취급할 수 있습니다.
일반적으로 클라이언트와 서버의 통신방법은 동기 방식입니다. 동기 방식이란 요청(request)이 있으면 응답(response)을 동시에 처리하는 방식을 말합니다. 이러한 동기 방식에서는 쓰레드(Thread) 하나가 요청을 가지고 오면 서버가 응답을 줄때까지 기다리게 됩니다. 쓰레드가 응답이 올때까지 아무것도 하지 못하는 상태를 Block 상태라고 합니다.
이러한 Block 방식은 요청에 대한 응답이 보장됩니다. 비록 응답에 실패하더라도 그 실패값이라도 보장 받게 됩니다. 따라서 동기식 통신은 요청에 대한 응답이 보장되어야 하는 환경에 적합합니다. (금융 결제 등)
웹 소캣에서 활용되는 비동기 통신 방식은 요청과 응답이 동시에 처리되지 않는 통신 방식입니다. 쓰레드가 요청을 전달하고 응답을 기다리는 것이 아니라 다음 요청을 계속 전달할 수 있습니다. 이러한 쓰레드의 상태를 Non Block 상태라고 합니다.
Non Block의 특성 때문에 순서상 늦게 온 요청이 먼저 온 요청보다 먼저 응답을 받을 수 있습니다. 즉, 비동기 방식은 요청 처리 순서를 보장하지 않습니다.
또한 Non Block의 특성 때문에 비동기 방식이 동기 방식에 비해 성능이 좋을 수밖에 없습니다. 하지만 동기식과는 방대로 응답에 대한 처리 결과를 보장받아야 하는 서비스에는 적합하지 않습니다.
오리진이란 서버의 위치를 의미합니다. 웹 환경에서 서버의 위치는 url로 표현될 수 있고, 우리가 일상적으로 마주치는 url의 특정 부분이 오리진입니다.
이 그림에 잘 표현되어 있는데, url 전체중에서 protocol, hostname, port 이 세개를 통틀어서 오리진이라고 합니다.
정보 출처
blog.2020
javascript.info
웹을 개발하다보면 굳이 서버나 DB에 저장하지 않아도 될 정도로 중요하지 않고 유실되어도 되는 데이터가 있을 수 있습니다. 이러한 데이터 저장을 위해 서버와 DB의 리소스를 사용하는 것은 낭비이기 때문에 클라이언트 단에서 데이터를 저장하는데, 그 공간이 웹 스토리지 입니다.
웹 스트리지 종류에는 로컬 스토리지와 세션 스토리지가 있습니다. 세션 스토리지는 웹페이지의 세션이 끝날 때 저장된 데이터가 지워지는 반면에, 로컬 스토리지는 웹페이지의 세션이 끝나더라도 데이터가 지워지지 않습니다.
세션 스토리지는 각 브라우저 창마다 격리되어 유지, 소멸하지만 로컬 스토리지는 모든 브라우저 창이 공유합니다. 따라서 브라우저는 닫아도 데이터는 그대로 남아있게 됩니다. 하지만 이러한 로컬 스토리지의 데이터 영속성은 어디까지나 계속해서 동일한 브라우저를 사용할 때만 해당되빈다. 같은 컴퓨터에서 다른 부라우저를 사용하면 서로 다른 로컬 스토리지에 데이터를 저장하게 됩니다.
교차 출처 리소스 공유(Cross-Origin Resource Sharing)란 SOP정책의 예외조항으로, CORS를 지키지 않으면 오리진이 다른 서버와 클라이언트간의 소통에서 서버의 응답이 버려진다.
SOP(Same-Origin Policy)는 지난 2011년, RFC 6454에서 처음 등장한 보안 정책으로 말 그대로 “같은 출처에서만 리소스를 공유할 수 있다”라는 규칙을 가진 정책이다.
그러나 웹이라는 오픈스페이스 환경에서 다른 출처에 있는 리소스를 가져와서 사용하는 일은 굉장히 흔한 일이라 무작정 막을 수도 없는 노릇이니 몇 가지 예외 조항을 두고 이 조항에 해당하는 리소스 요청은 출처가 다르더라도 허용하기로 했는데, 그 중 하나가 “CORS 정책을 지킨 리소스 요청”이다.
정보출처
blog.2020
STOMP(Streaming, or Simple Text Oriented Messaging Protocol) , 웹 소캣을 이용하면 HTTP가 아닌 STOMP를 이용해서 통신을 하게됨,
웹 소캣에 이용되며, cloud native, microservices-based, serverless and hybrid cloud architectures 분야에 응요되는듯
메시지 브로커는 어플리케이션, 시스템, 서비스간에 의사소통과 정보교환을 가능케 하는 소프트웨어 입니다. 메시지 브로커는 정형화된 메시지 프로토콜(formal messaging protocol)간의 메시지를 변환함으로써 이러한 일을 수행합니다. 메시지 브로커를 통해 상호의존적인 서비스들은 서로 다른 언어, 플랫폼에서 구현되었다고 하더라도 '대화'할 수 있습니다.
A message broker is software that enables applications, systems, and services to communicate with each other and exchange information. The message broker does this by translating messages between formal messaging protocols. This allows interdependent services to “talk” with one another directly, even if they were written in different languages or implemented on different platforms.
messaging middleware 혹은 message-oriented middleware
/**
* @EnableWebSocketMessageBroker enables WebSocket message handling, backed by a message broker.
* what is message broker?
*
*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/gs-guide-websocket").withSockJS();
}
/**
* The configureMessageBroker() : message broker를 설정(config) 하기 위한 메서드이다.
*
* enableSimpleBroker : to enable a simple memory-based message broker
* to carry the greeting messages back to the client on destinations prefixed with /topic
* 그외에 어떤 Broker 설정이 있을까
*
* setApplicationDestinationPrefixes : 모든 @MessageMapping 에 묶여있는 메시지 핸들러에 prefix 적용, 즉,
* 아래의 Controller 메서드는 /app/hello 에서 message를 받는다. (endpoint)
*
* @MessageMapping("/hello")
* @SendTo("/topic/greetings") // 여기로 보낸다.
* public Greeting greeting(HelloMessage message) {...}
*
*
* The registerStompEndpoints() : method registers the /gs-guide-websocket endpoint,
* enabling SockJS fallback options so that alternate transports can be used
* if WebSocket is not available. The SockJS client will attempt to connect
* to /gs-guide-websocket and use the best available transport
* (websocket, xhr-streaming, xhr-polling, and so on).
*/
}
@Controller
public class GreetingController {
/**
* The @MessageMapping annotation ensures that,
* if a message is sent to the '/hello' destination, the greeting() method is called.
*
* The return value is broadcast to all subscribers of /topic/greetings,
* as specified in the @SendTo annotation
*/
@MessageMapping("/hello") // 여기서 받아서
@SendTo("/topic/greetings") // 여기로 보낸다.
public Greeting greeting(HelloMessage message) throws Exception {
Thread.sleep(1000); // simulated delay
return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
}
}
왜 같은 url에서 메시지가 보이지 SendTo 로 받을때 url이 바뀔 필요가 없나