노마드코더님의 웹소켓 개념 강의를 보고 정리한 내용
오랜만에 아이패드로 글씨쓰니까 🐶🐶🐶판이다!!
웹소켓이 모든 브라우저에서 지원되는 것이 아니다. firefox
, safari
, internet explorer
구버전에서는 지원되지 않는데, 이 때 스프링이 제공해 주는 SockJs
, Socket.io
라이브러리를 사용하여 웹소켓을 사용하는 것처럼 보이게 할 수있다.
밑은 SockJs가 어떻게 지원하는지 나와있는 표이다.
Client
는 handshake 요청 메세지를 Server
에게 보낸다.Server
는 handshake 응답 메세지를 Client
에게 보낸다.Client
는 data payload frames를 server
에게 보낸다.Server
는 data payload frames를 Client
에게 보낸다.Client
는 close frame을 Server
에게 보낸다.Server
는 close frame을 Client
에게 보낸다.• 최초 접속에서만 http프로토콜 위에서 handshacking을 하기 때문에 http header를 사용한다.
• webSocket을 위한 별도의 포트는 없으며, 기존 포트(http:80, https:443)를 사용한다.
• webSocket 프로토콜의 ws는 http기반으로 운영되고, wss는 https기반으로 운영된다.
• 메시지(Upgrade:WebSocket, Connection:Upgrade)
• 메시지에 포함될 수 있는 교환 가능한 메세지는 text와 binary이다.
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;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketTextHandler(), "/user")
.setAllowedOrigins("*")
.withSockJS();
}
}
• Configuration
클래스를 생성 / @EnableWebSocket
어노테이션 설정 / WebSocketConfigurer
/ registerWebSocketHandlers
• 웹소켓을 사용하려면 클라이언트가 보내오는 통신을 처리할 handler가 필요하다.
• addHandler method : SocketTextHandler()
->아론님이 직접 구현하신 웹소켓 핸들러, /user
-> 웹소켓 연결 주소(핸드쉐이크할 주소)
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.json.JSONObject;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.RextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
public class SocketTextHandler extends TextWebSocketHandler {
private final Set<WebSocketSession> sessions = ConcurrentHashMap.newKeySet();
@Override
public void afterConnectionEstablished(WebSocketSession session) {
sessions.add(session);
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
JSONObject jsonObject = new JSONObject(payload);
for (WebSocketSession s : sessions) {
s.sendMessage(new TextMessage( payload : "Hi" + jsonObject.get("user") + "! How may I help you?"));
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throw Exception{
session.remove(session);
}
}
• 웹소켓은 기본적으로 텍스트 또는 바이너리 타입을 지원한다.
• 필요에 따라 TextWebSocketHandler
또는 BinaryWebSocketHandler
라는 스프링이 제공하는 기본클래스를 상속하여 구현하면 된다.
•WebSocketSession
: http세션과는 조금 다름, 웹소켓이 연결될 때 생기는 연결 정보를 담고 있는 객체. 핸들러에서 웹소켓 통신에 대한 처리를 하기 위하여 이 세션들을 컬렉션으로 담아 관리하는 경우가 많다. Set<WebSocketSession>
• 커넥션이 맺어질 때 컬렉션에 웹소켓 세션을 추가하고 커넥션이 끊어질 때 제거한다.
• 연결되어있는 모든 클라이언트들에게 메세지를 보낼 수 있게 된다.
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;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSockerHandlerRegistry registry) {
registry.addHandler(new SocketTextHandler(), "/user")
.setAllowedOrigins("*")
.withSockJS();
}
}
• WebSocket도 CORS 정책을 지켜야 한다. 이를 해결하기 위하여 .setAllowedOrigins("*")
를 붙여 CORS정책을 위반하지 않게 할 수 있다.
• .withSockJS()
한 줄을 추가하면, 지원하지 않는 범위의 브라우저에서도 웹소켓과 비슷하게 사용할 수 있게 할 수 있다.
오오 웹소켓 도전 가시나요?