다음 튜토리얼은 회사의 개발에 참여한 회사의 CRM 시스템이며 관련 정보를 정리했습니다. 시스템에는 많은 메시지 푸시 기능이 있으며 WebSocket 기술이 사용됩니다. 다음 편집자는 참조를 위해 Wulin 네트워크 플랫폼에서 컴파일되어 공유했습니다.
1. Maven 의존성
<pectionency> <groupId> javax.servlet </groupId> <artifactid> javax.servlet-api </artifactid> <bersion> 3.1.0 </version> </dependency> <prectionency> <groupId> com.fasterXML.Core.core </groupId> <artifactid> Jackson-Core </artifactid> <버전> 2.3. 0 </version> </dependency> <pectinement> <groupId> com.fasterXml.jackson.core </groupId> <artifactid> Jackson-Core </artifactid> <bersion> 2.3.0 </dependency> <pectionency> <groupid> com.fasterxml.jackson.core </groupid> jackson -databind </artifactid> <3.3.0 </version> </fectionency> <prectionement> <groupid> org.springframework </groupid> <artifactid> spring-websocket </artifactid> <버전> 4.0.1. 릴리스 </version> </dependency> <pectinement> <groupId> org.springframework </groupid> <artifactid> Spring-messing </artifactid> <bersion> 4.0.1. Release </version> </dependency>
2. 스프링 서비스 구성
<? xml 버전 = "1.0"encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans"xmlns : context = "http://www.springframework.org/schema/cont ext "xmlns : mvc ="http://www.springframework.org/schema/mvc "xmlns : tx ="http://www.springframework.org/schema/tx " xmlns : xsi = "http://www.w3.org/2001/xmlschema-instance"xmlns : websocket = "http://www.springframework.org/schema/websocket"xsi : schemalocation = "http : // www .springframework.org/schema/beanshttp : //www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp : //www.springframework.org/schema/context/spring -Context-3.1.xsdhttp : //www.springframework.org/schema/mvchttp : //www.springframework.org/schema/mvc/spring-mvc-3.1.xsdhttp : //www.springframework.org/schema/txhme/txhma/txhma/txhme ingframework.org/schema/tx/spring-tx-3.1.xsdhttp://www.springframework.org/schema/websocketthttp://www.springframework.org/schema/websocket/spring-websocket.xsd"> <boet--> webocket-> bean id = "websocket"/> <websocket : handlers> <websocket : 매핑 경로 = "/websocket"handler = "WebSocket"/> <WebSocket : Handshake-Interceptors> <bean/> <Websocket : Handshake-Interceptors> </websocket : handlers> </beans>
그중에서도 경로에 해당하는 경로는 이전 섹션의 WS 프로토콜을 통해 조정 된 인터페이스 경로입니다.
3. Handshakeinterceptor의 구현
패키지 cn.bridgeli.websocket; import cn.bridgeli.utils.usermanager; import cn.bridgeli.util.dateutil; import cn.bridgeli.sharesession.userinfo; import org.apache.commons.lang.stringutils; import org.slf4j.logger; org.slf4j.loggerfactory; import org.springframework.http.server.serverhttprequest; import org.springframework.http.server.serverhttpresponse; import org.springframework.web.context.request.requestconcontecontextloxtoldoxtoldoxtloxtontoxtontoxtont org.springframework.web.context.request.servletrequestattributes; import org.springframework.web.socket.websockethandler; import org.springframework.web.socket.server.support.httpessessionhandshakeintercepor; import java.util.date; @description : 핸드 셰이크 인터페이스* @Date : 16-3-3*/public class 핸드 셰이크 인터셉터 확장 httpssessionHandshakeinterceptor {private static final logger = loggerfactory.getLogger (핸드 셰이크 interceptor.class); @witridepublic bolean 사전 핸드 셰이크 (ServerHtpRequest resignder, westhtprest resapond, webstrsprest) WSHANDLER, MAP <String, Object> Attributes)는 예외를 {logger.info ( "핸드 셰이크를 만들기 전에 ..."); servletRequestAttributes attrs = (servletRequestAttributes) requestContexTholder.getRequestattributes (); userInfo curruser = userQuestestesser (interrequest (getrs.getS) userocketvo (); String email = ""; if (null! = curruser) {email = curruser.getEmail ();} if (stringUtils.isblank (email)) {email = dateUtil.date2string (new Date ());} userSocketVo.SetUserEmail (email); attributes.put ( "session_user", usersocketvo); return super.beforeHandshake (요청, 응답, wshandler, 속성);}@reveridepublic void ajecthake (serverhttprequest request, serverhttpresponse 응답, websockethandler wshandler, exception ex) {logger.info ( "핸드 쉐이크 생성 후 ...")}}}} {wshandler, reponce, wshandler, expterhandshake.잘 이해하지 못하기 때문에 원래 코드를 최대한 유지합니다. 이것은 실제로 단일 로그인에서 현재 로그인 사용자를 꺼내서 userocketvo 객체로 변환 한 다음 맵에 넣는 것입니다. 그래서 userocketvo 객체의 정의를 살펴 보겠습니다.
4. userocketvo의 정의
패키지 cn.bridgeli.websocket; import org.springframework.web.socket.websocketsession; import java.util.date;/*** @description : 사용자 소켓 연결 엔티티*@Date : 16-3-7*/public class userOcketVO {private string useremail; // 사용자 이메일 비공개 날짜 연결 시간; // 성공적인 연결 시간 프라이버시 날짜 사전 4 시간; // 마지막 요청 시간 개인 날짜 NewRequestTime; // 새 요청 시간 개인 날짜 lastSendTime = 새 날짜 (); // 제거 메시지의 마지막 발송 시간 개인 날짜 lastAskSendTime = new Date (); // 보류중인 작업의 마지막 발송 시간 개인 webSocketSession webSocketSession; // 사용자에 해당하는 wssession은 기본적으로 하나만 캐시합니다. // getxx 및 setxx}가장 중요한 것은 WebSocketSession 속성이며 나중에 사용할 것입니다.
5. WebSocketEndpoint의 구현
패키지 cn.bridgeli.websocket; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.beans.beans.annotation.autowired; import org.spramframework.web.socket.closestatus; import org.springsate; wectring orgb.sxteets; org.springframework.web.socket.websocketsession; import org.springframework.web.socket.handler.textwebsockethandler;/*** @description : websocket processing class*@date : 16-3-3*/public class websocketpoint 확장 TextWebSocketHandler {private websockethandler {private logger { loggerfactory.getLogger (Websocketendpoint.class);@autowiredPrivate NewsListenerImpl NewsListener; @OverRideProtected void handleTextMessage (websocketSession Session, TextMessage Message) 예외 {super.HandleTextSmessage (세션, 메시지); 텍스트 MESSAGE (reportSage at at at at at at at at emesse.getPaysage). 서버 "); session.sendMessage (returnMessage);}/*** @description : 연결을 설정 한 후* @param session* @throws exception*/ @atriadepublic void alfconnectionestablished (websocketsession session)는 {userocketvo userocketvo = (userSocketVo) session.get ("session_user "); if (null! = userocketvo) {userocketvo.setwebsocketsession (session); if (wssessionlocalcache.exists (userocketvo.getuseremail ())) {wssessionlocalcache.remove (userocketvo.getuseremail ());} wssessionlocalcache.put (usersocketvo.getuseremail (), userocketvo); newsListener.AfterConnectionStablish (userocketvo.getUserEmail ());} logger.info ( "소켓이 성공적으로 설정 ..."); super.AfterConnectionStablish (세션);}@atedridepublic void afterConnectionClosed (websocketSession session, closestatus status) {usecketSection status) {useedcetsocket vo. (userocketvo) session.getattributes (). get ( "session_user"); if (null! = userocketvo) {wssessionlocalcache.remove (userocketvo.getuseremail ());} logger.info ( "소켓이 연결을 성공적으로 닫았습니다 ...")6. wssessionlocalcache의 구현
패키지 cn.bridgeli.websocket; import java.io.serializable; import java.util.arraylist; import java.util.hashmap; import java.util.list; import java.util.map;/*** @description; Serializable {private static map <string, userocketvo> wssessioncache = new Hashmap <> (); public static boolean (string useremail) {if (! wssessioncache.containskey (useremail)) {return;} else {return}} public static void put (string useremail, string useremovo userocketvo) {wssessioncache.put (useremail, userocketvo);} public static userocketvo get (string useremail) {return wssessioncache.get (useremail);} public static void remove (string useremail) {usssessioncache.remove (useremail) <usersocketvo> getallo> getsongsessess (useromecoce). ArrayList <> (wssessionCache.Values ());}}구현을 살펴본 후 효과가 더 분명합니다. 각 usersocketvo의 최신 데이터를 저장합니다. 실제로, 우리의 WebSocket 구현은 여기에서 계산되었지만 여전히 구현되지 않은 핵심 클래스 (Charlie 's Class)가 있습니다. 다음 기사 인 Spring Integrated WebSocket 응용 프로그램 예제 (2 부)에서는이 클래스를 구현하는 방법을 볼 수 있습니다.
WebSocket 프로토콜 소개
WebSocket 프로토콜은 RFC-6455 사양에 의해 정의 된 웹 필드의 중요한 기능입니다. 전체 듀플렉스, 즉 클라이언트와 서버 간의 양방향 통신. 흥미로운 기능입니다. 업계는이 분야를 오랫동안 탐색 해 왔습니다. 사용 된 기술로는 Java Applet, XMLHTTPREQUEST, Adobe Flash, ActiveXobject, 다양한 혜성 기술, 서버 측 전송 이벤트 등이 있습니다.
WebSocket 프로토콜을 사용하기 전에 HTTP 프로토콜을 사용하여 초기 핸드 셰이크를 구축해야한다는 것을 이해해야합니다. 이는 HTTP 설정 및 프로토콜 업그레이드 (또는 프로토콜 변환)를 요청하는 메커니즘에 의존합니다. 서버가 동의하면 HTTP 상태 코드 101에 응답하여 프로토콜을 전환하는 데 동의 함을 나타냅니다. TCP 소켓과 HTTP 프로토콜 업그레이드 요청을 통한 성공적인 핸드 셰이크가 전달되었다고 가정하면 클라이언트와 서버가 서로 메시지를 보낼 수 있습니다.
Spring Framework 4.0 이상은 새로운 모듈, 즉 Spring-Websocket 모듈을 도입했습니다. WebSocket 커뮤니케이션을 지원합니다. 추가 기능을 제공하면서 Java WebSocket API 사양 JSR-356과 호환됩니다.
WebSocket을 사용해야하는 시나리오에서
웹 애플리케이션에서 클라이언트와 서버가 더 높은 주파수 및 낮은 대기 시간으로 이벤트를 교환 해야하는 경우 WebSocket에 적합합니다. 따라서 WebSocket은 금융, 게임 및 협업과 같은 응용 프로그램 시나리오에 적합합니다.
다른 응용 프로그램 시나리오에는 적합하지 않을 수 있습니다. 예를 들어, 뉴스 구독은 뉴스를 나누어야하며 몇 분 간격으로 긴 설문 조사를 사용해도 괜찮으며 여기에서 지연이 허용됩니다.
대기 시간이 낮은 응용 프로그램에서도 전송 된 메시지 수가 매우 낮 으면 (예 : 네트워크 고장 모니터링) 긴 폴링 기술을 고려해야합니다.
대기 시간이 낮고 고주파 메시지 통신이있는 시나리오에서만 WebSocket 프로토콜을 선택하는 것이 매우 적합합니다. 이러한 응용 프로그램 시나리오에서도 WebSocket Communication을 선택할 수 있습니까? 또는 REST HTTP 커뮤니케이션을 선택 하시겠습니까?
답은 응용 프로그램의 요구에 따라 다를 것이라는 것입니다. 그러나이 두 기술을 동시에 사용하여 자주 WebSocket으로 교환 해야하는 데이터를 넣고 나머지 API를 프로세스 기반 비즈니스 구현 기술로 사용하는 것도 가능합니다. 또한 REST API 호출에서 특정 정보를 여러 클라이언트로 방송 해야하는 경우 WebSocket 연결을 통해 구현할 수도 있습니다.
Spring Framework는 @Controller 주석 및 @RestController 주석을 제공하며, 둘 다 HTTP 요청 처리 및 WebSocket 메시지 처리에 사용할 수 있습니다. 또한 Spring MVC 요청 처리 방법 또는 기타 응용 프로그램 요청 처리 방법은 WebSocket 프로토콜을 사용하여 모든 관심있는 고객 또는 지정된 사용자에게 메시지를 방송 할 수 있습니다.