WebSocket
들어가기 전
long polling
- 완전한 실시간이 아님
- 1초마다 한번씩 계속 요청, 부하가 너무 큼
Server Sent Event
- 서버와 클라이언트 사이에서 통로하나가 유지됨
- 메시지이벤트가 발생하고 서버사이드에서 발생한 이벤트에 대한 정보를 담아서 보냄
- 단점
- 서버에서 클라이언트에게로만 일방적 전송 (푸시메세지에 적합)
- 고정된 형태로만 메시지 전송됨
HTTP/1.1
- 1.1에 새로나온 개념: Web Socket
- 서버프로토콜인 웹소켓을 사용하게 되면...
- 클라이언트와 서버간 통로를필요할때 개설할 수 있음
- 필요 업서지면 내가 원할 때 끊을 수 있음
- 라이프사이클을 직접 제어할 수 있음
- 직접 제어할수 있다라면 통로개방후 계속 유지할 수 있다는 얘기
- 통로개방이 유지된다면 실시간 양방향 통신도 가능하다는것
- 단점
- 서버는 하나, 클라이언트는 여럿 -> 부하 발생
- HTTP를 STATEFULL로 운영하는 것과 차이점
- WEBSOCKET은 헤더정보는 포함이 되지않은채 콕집어서 데이터만 주고받음 -> 오고 가는 데이터양의 그렇게 크지 않음
- 최소한의 데이터를 주고받는 통로를 개방하는 과정에서 WEBSOCKET 프로토콜을 사용
주안점
- 통로를 어떻게 개설할 것인가?
- 통로를 통해 데이터를 보내는 방법
- 통로를 통해 데이터를 받는 방법
- 통로를 끊는 방법
- 위의 4가지를 처리하는 방법: JAVASCRIPT의 WEBSOCKET API
테스트
PDF
- 1~8p 기본
- 9~ : 스프링3버전으로 구현, 자바core-api만으로 구현하는 방법
- 14~18: 서버 사이드 구현 방법 (스프링4이상)
- 19~: 클라이언트사이드 방법, 자바스크립트 웹소켓
Spring WebSokcet API
기본 에코 웹소켓 구현
1. dependency 추가
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${org.springframework.security-version}</version>
</dependency>
2. WebSocketHandler 의 구현
- text/binary
- WebSocketSession: 연결 수립 후 연결 끊길때까지 살아있는 세션
- httpsession과는 완전히 다르다
- http는 연결끊겨도 세션이 살아있기 때문에
afterConnectionEstablished (=onopen)
afterConnectionClosed (=onclose)
handleTextMessage (=onmessage)
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
session.sendMessage(new TextMessage(payload));
}
handleTransportError (=onerror)
3. 구현한 핸들러를 WebSocketEndpoint로 등록 : handshake URL 매핑.
- 하위컨테이너에 websocket-context 등록
- web.xml의 dispatcherservlet에서 해당 context 등록
- 로딩 순서에 따라 기술
인가된 사용자와의 채팅
HttpSession 과 WebSocketSession 간의 데이터 공유(Handshaking 커스터마이징)
- Handshake Interceptor
- Handler Interceptor: 요청이 커맨드핸들러로 넘어가기전 전처리 후처리를 하는 애였음, Handshake Interceptor도 비슷한 역할
- handshaking 발생과정에서 가로채서 HttpSession에 있던걸 WebsocketSession에 옮겨줘야하고, 그 과정에서 httpSession에 들어있는 authentication 정보까지 옮겨담아야함
- 이작업이 이미 HttpSessionHandshakeInterceptor에 구현되어있으니interceptor로 등록해서 써먹기만 하면 됨
<websocket:handlers>
<websocket:mapping handler="echoTestWebSocketHandler" path="/echo"/>
<websocket:handshake-interceptors>
<bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"
p:copyAllAttributes="true"
p:copyHttpSessionId="true"
/>
</websocket:handshake-interceptors>
</websocket:handlers>
가입/탈퇴 시 접속자에게 푸시알림
- 이벤트 먼저 정의되어야함
- 이벤트 처리 핸들러 필요
- 이벤트 발생 시 리스너로 연계해주는 '누군가'가 필요
3.1 누군가: ApplicationEventPublisher (이벤트 발행자)
기타
event-driven / test-driven
event-driven model
- 어플리케이션 플로우 형성시 이벤트 처리 핸들러를 통해 형성함
- 모든것이 이벤트 처리구조로
- 어떤 상황이 발생했을 때 이벤트 처리하기 위한 방식으로 가는것
- ex 시큐리티에서 로그인 성공시 LoginSuccessHanlder로 처리함
- ex 웹소켓
test-driven model
- 로직을 먼저 짜는게 아닌 테스트 케이스를 먼저 만듬
- 테스트 케이스에 맞는 여러 상황을 생각해 본 후에 로직을 짬