Spring

[Spring] WebSocket sockJS Q&A 실시간 알림 구현하기 (1)

hellooooo 2021. 11. 11. 17:11
728x90

WebSocket  : 웹소켓에서는 서버와 브라우저 사이에 양방향 소통이 가능 

웹 소켓은 HTML5 이후에 나왔기 때문에 Socket.io와 SockJS 이용해서 HTML5 이전 기술로 구현된 서비스에서도 웹 소켓처럼 사용할 수 있다. 클라이언트쪽은SockJS client를 통해 서버와 통신한다.

그래서 javaScript에서 sockJS 이용하여 실시간 알림을 구현해보려고 한다.

[ 세팅 부분 ]

pom.xml (= Maven 설정) 

https://mvnrepository.com/artifact/org.springframework/spring-websocket

<!-- https://mvnrepository.com/artifact/org.springframework/spring-websocket -->
<!--  웹소켓 추가  -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
    <groupId>javax.websocket</groupId>
    <artifactId>javax.websocket-api</artifactId>
    <version>1.1</version>
</dependency>
<!--  웹소켓 끝  -->

web.xml  또는 EgovWebApplicationInitializer.java 

1. <async-supported> true </async-supported> 추가 

<servlet> 
    <servlet-name>action</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/config/egovframework/springmvc/egov-com-*.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
</servlet>

2. egovframework일경우 EgovWebApplicationInitializer.java 파일에 .setAsyncSupported(true) 추가 

일반적으로 스프링 구동순서는 web.xml에서 파일들을 읽어오는데 공통컴포넌트는 EgovWebApplicationInitializer.java에서 시작

ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(xmlWebApplicationContext));
dispatcher.addMapping("*.do");
dispatcher.setLoadOnStartup(1);
dispatcher.setAsyncSupported(true);

egov-com-sevlet.xml (=핸들러 등록) 

* WebSocket Handshake : 웹소켓 핸들러 클래스(echoHandler)가 호출되기 전에 HttpSession에 접속하여  이용자 아이디를 추출하는 기능 등을 인터셉터가 수행하도록 설정 

<!-- 웹 소켓핸들러 -->
<websocket:handlers>
   <websocket:mapping handler="WebSocketHandler" path="/websocket.do"/>
   <websocket:handshake-interceptors>
           <bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/>
   </websocket:handshake-interceptors>
   <!-- <websocket:sockjs /> -->
</websocket:handlers>
<bean id="WebSocketHandler" class="egovframework.pcr.main.common.controller.WebSocketHandler" />

WebSocketHandler.java 생성 (= TextWebSocketHandler을 상속받은 핸들러 클래스를 정의) 

@Repository
public class WebSocketHandler extends TextWebSocketHandler {
 @Override
 public void afterConnectionEstablished(WebSocketSession session) throws Exception{
 }

 @Override
 protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
 }

 @Override
 public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception{
 }
}

afterConnectionEstablished(), afterConnectionClosed() : 각각 웹소켓 클라이언트와 연결되거나 연결이 끊겼을 때 호출

HandleTextMessage() : 웹소켓 클라이언트가 텍스트 메시지를 전송할 때 호출

sockjs 추가 (1,2번중 선택) 

1. js 직접 다운로드 후 추가 

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

 

GitHub - sockjs/sockjs-client: WebSocket emulation - Javascript client

WebSocket emulation - Javascript client. Contribute to sockjs/sockjs-client development by creating an account on GitHub.

github.com

2. cdn으로 추가 

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.1.5/sockjs.min.js"></script>

jsp view단 세팅  

ws.onopen : 서버에 접속한 후 이벤트 정의 

ws.onmessage : 서버에서 Session.send를 이용해서 메시지 전송할 때 수신 이벤트 정의 

ws.onclose : 서버에서 접속 종료한 후 이벤트 정의 

ws.send : 서버에 메시지를 전송

 

 

JSP에서 ${pageContext.request} 정보 얻기

javax.servlet.http.HttpServletRequest 오브젝트가 제공하는 정보를 활용해서 정보를 얻을 수 있다. ${pageContext.request.scheme} http ${pageContext.request.serverName} localhost ${pageContext.request...

truecode-95.tistory.com

ws://localhost:8084${pageContext.request.contextPath}/websocket.do

같은 의미

ws://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/websocket.do   

<script>
    var socket = null;
	connect();

	function connect() {
        var ws = new WebSocket('ws://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/websocket.do');		   
        socket = ws;
        
		ws.onopen = function() {
       		console.log('Info: connection opened.');
		};

		ws.onmessage = function(event) {
       		console.log('Info: connection onmessage.');
		};

		ws.onclose = function(event) {
       		console.log('Info: connection closed');
		};
        
		ws.onerror = function(err) {
       		console.log('Error:', err);
		};
	}

	$(document).ready(function() {
		   socket.send();
		});
	   socket.onclose();
	});
</script>

 

 

 

 

 

 

 

 

 

 

 

 

 

[Spring] WebSocket sockJS Q&A 실시간 알림 구현하기 (2) 아래 링크 클릭 

 

[Spring] Q&A 등록시 실시간 알림 구현하기 (2) [WebSocket]

[ 개발 부분 ] package egovframework.pcr.main.common.controller; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.StringUtils; import org.apache.ib..

truecode-95.tistory.com

 

 

 

 

 

 

 

 

 

참고 : https://simsimjae.tistory.com/25

 

[스프링/spring] 웹 소켓을 활용한 쪽지 알람 기능(페이지 이동시)

이 사진 처럼 페이지를 이동할때마다 현재 나에게 도착한 쪽지의 개수를 출력 하는 방법을 알아 보겠습니다. 실시간 채팅, 실시간 알림 기능등에 사용되는 웹 소켓을 사용해서 구현 했습니다.

simsimjae.tistory.com