WebSocket+spring 예제 demo 자세히 보기(sockJs 라이브러리 사용)
차세대 웹 표준으로서 HTML5는 많은 사람들의 주목을 끄는 새로운 기능을 가지고 있다. 예를 들어 Canvas, 로컬 저장소, 멀티미디어 프로그래밍 인터페이스, WebSocket 등이다.이 중'웹의 TCP'라고 불리는 웹소켓은 특히 개발자들의 주의를 끈다.WebSocket의 등장으로 브라우저가 Socket에 대한 지원을 제공할 수 있게 되었고 브라우저와 서버 사이에 TCP 연결을 기반으로 하는 양방향 채널을 제공했다.웹 개발자는 웹 소켓을 이용하여 실시간 웹 응용 프로그램을 구축하는 데 매우 편리하게 사용할 수 있고 개발자의 손에는 이때부터 또 하나의 신병기가 생겼다.
웹 응용 프로그램의 정보 상호작용 과정은 일반적으로 클라이언트가 브라우저를 통해 요청을 보내고 서버 측이 요청을 접수하고 심사한 후에 처리하고 결과를 클라이언트에게 되돌려 주는 것이다. 그리고 클라이언트 브라우저는 정보를 나타낸다. 이런 메커니즘은 정보 변화가 특별히 빈번한 응용에 대해 안전하지 않다. 그러나 실시간 요구가 비교적 높은 응용에 있어 예를 들어 온라인 게임, 온라인 증권,장치 모니터링, 뉴스 온라인 방송, RSS 구독 푸시 등, 클라이언트 브라우저가 이러한 정보를 보여줄 준비를 할 때 이러한 정보는 서버에서 이미 유행이 지났을 수 있다.
따라서 클라이언트와 서버 측의 정보 동기화를 유지하는 것은 실시간 웹 응용의 관건적인 요소로 웹 개발자에게도 어려운 문제이다.WebSocket 규범이 나오기 전에 개발자들이 이러한 실시간 웹 응용을 실현하려면 절충된 방안을 채택해야 한다. 그 중에서 가장 자주 사용하는 것이 바로 폴링(Polling)과 Comet 기술이다. Comet 기술은 사실상 폴링 기술의 개선이고 두 가지 실제 방식으로 세분화할 수 있다. 하나는 긴 폴링 메커니즘이고 하나는 흐름 기술이라고 한다.
Html5 WebSocket이 디자인한 목적은 윤문과Comet 기술을 대체하여 클라이언트 브라우저가 C/S 구조의 데스크톱 시스템과 같은 실시간 통신 능력을 갖추도록 하는 것이다.브라우저는 JavaScript를 통해 서버에 WebSocket 연결을 요청합니다. 연결이 이루어지면 클라이언트와 서버 측은 TCP 연결을 통해 직접 데이터를 교환할 수 있습니다.WebSocket 연결은 본질적으로 하나의 TCP 연결이기 때문에 데이터 전송의 안정성과 데이터 전송량의 크기에 있어 윤문과Comet 기술과 비교하면 매우 큰 성능 우위를 가진다.
그러나 웹 socket이 브라우저에 대한 요구가 비교적 높다는 것을 감안하여 이 문제를 해결하기 위해 sockJS를 출시했습니다. SockJS는 자바스크립트 라이브러리로 크로스 브라우저javascript의 API를 제공하고 낮은 지연, 완전 이중화된 브라우저와 웹 서버 간의 통신 채널을 만들었습니다.
2. 관련 환경 요구 사항
Spring4.0.6(4.0+ 선택 가능), tomcat7.0.55 버전, JDK1.7
3. 구체적인 코드
(아래 코드 직접 측정 가능!)
(1)web.xml:
<?xmlversionxmlversion="1.0"encoding="UTF-8"?>
<web-app version="3.1"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<description> WebSocket </description>
<distributable/>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring Introspector -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>testSocket.jsp</welcome-file>
</welcome-file-list>
</web-app>
(2) dispatcher-servlet.xml
<?xmlversionxmlversion="1.0"encoding="UTF-8"?>
<beans:beansxmlnsbeans:beansxmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<annotation-driven/>
<!-- -->
<context:component-scanbase-packagecontext:component-scanbase-package="zyy.sockjs.config"></context:component-scan>
</beans:beans>
(3)HandshakeInterceptor.java
package zyy.sockjs.config;
import java.util.Map;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
@Component
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
System.out.println("Before Handshake");
return super.beforeHandshake(request,response,wsHandler,attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
System.out.println("After Handshake");
super.afterHandshake(request,response,wsHandler,ex);
}
}
(4)InfoSocketEndPoint.Java
package zyy.sockjs.config;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
@Component
public class InfoSocketEndPoint extends TextWebSocketHandler {
public InfoSocketEndPoint() {
}
@Override
protected void handleTextMessage(WebSocketSession session,
TextMessage message) throws Exception {
super.handleTextMessage(session, message);
TextMessage returnMessage = new TextMessage(message.getPayload()
+ " received at server");
session.sendMessage(returnMessage);
}
}
(5)SystemWebSocketHandler.java
package zyy.sockjs.config;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
/**
*
* @author dayu
*/
@Component
public class SystemWebSocketHandler implements WebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("connect to the websocket success......");
session.sendMessage(new TextMessage("Server:connected OK!"));
}
@Override
public void handleMessage(WebSocketSession wss, WebSocketMessage<?> wsm) throws Exception {
TextMessage returnMessage = new TextMessage(wsm.getPayload()
+ " received at server");
wss.sendMessage(returnMessage);
}
@Override
public void handleTransportError(WebSocketSession wss, Throwable thrwbl) throws Exception {
if(wss.isOpen()){
wss.close();
}
System.out.println("websocket connection closed......");
}
@Override
public void afterConnectionClosed(WebSocketSession wss, CloseStatus cs) throws Exception {
System.out.println("websocket connection closed......");
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}
(6)WebSocketConfig.java
package zyy.sockjs.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.WebSocketHandler;
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
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements
WebSocketConfigurer {
public WebSocketConfig() {
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(systemWebSocketHandler(), "/websck").addInterceptors(new HandshakeInterceptor());
System.out.println("registed!");
registry.addHandler(systemWebSocketHandler(), "/sockjs/websck/info").addInterceptors(new HandshakeInterceptor())
.withSockJS();
}
@Bean
public WebSocketHandler systemWebSocketHandler() {
return new SystemWebSocketHandler();
}
}
(7)testSocket.jsp
<%@ page language="java"contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE htmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=ISO-8859-1">
<title>WebSocket/SockJS Echo Sample (Adapted from Tomcat's echo sample)</title>
<style type="text/css">
#connect-container {
float: left;
width: 400px
}
#connect-container div {
padding: 5px;
}
#console-container {
float: left;
margin-left: 15px;
width: 400px;
}
#console {
border:1px solid #CCCCCC;
border-right-color:#33333333;
border-bottom-color:#999999;
height: 170px;
overflow-y: scroll;
padding: 5px;
width: 100%;
}
#console p {
padding: 0;
margin: 0;
}
</style>
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<script type="text/javascript">
var ws = null;
var url = null;
var transports = [];
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('echo').disabled = !connected;
}
function connect() {
if (!url) {
log('Select whether to use W3C WebSocket or SockJS');
return;
}
//ws = (url.indexOf('sockjs') != -1) ?new SockJS(url, undefined, {protocols_whitelist: transports}) : new WebSocket(url);
if ('WebSocket'in window) {
ws= new WebSocket("ws://localhost:8080/SpringSocketJs/websck");
}else {
ws = new SockJS("http://localhost:8080/SpringSocketJs/sockjs/websck/info");
}
//websocket = new SockJS("http://localhost:8084/SpringWebSocketPush/sockjs/websck");
ws.onopen = function () {
setConnected(true);
//log('Info: connection opened.');
};
ws.onmessage = function (event) {
log('Received: ' + event.data);
};
ws.onclose = function (event) {
setConnected(false);
log('Info: connection closed.');
log(event);
};
}
function disconnect() {
if (ws != null) {
ws.close();
ws = null;
}
setConnected(false);
}
function echo() {
if (ws != null) {
var message = document.getElementById('message').value;
log('Sent: ' + message);
ws.send(message);
} else {
alert('connection not established, please connect.');
}
}
function updateUrl(urlPath) {
if (urlPath.indexOf('sockjs') != -1) {
url = urlPath;
document.getElementById('sockJsTransportSelect').style.visibility ='visible';
}
else {
if (window.location.protocol =='http:') {
url = 'ws://' + window.location.host + urlPath;
} else {
url = 'wss://' + window.location.host + urlPath;
}
document.getElementById('sockJsTransportSelect').style.visibility ='hidden';
}
}
function updateTransport(transport) {
transports = (transport == 'all') ? [] : [transport];
}
function log(message) {
var console = document.getElementById('console');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(message));
console.appendChild(p);
while (console.childNodes.length > 25) {
console.removeChild(console.firstChild);
}
console.scrollTop = console.scrollHeight;
}
</script>
</head>
<body>
<noscript><h2 style="color:#ff0000">Seems your browser doesn't supportJavascript!Websockets
rely on Javascript being enabled. Please enable
Javascript and reload this page!</h2></noscript>
<div>
<div id="connect-container">
<input id="radio1"type="radio"name="group1"onclick="updateUrl('/SpringSocketJs/websocket');">
<label for="radio1">W3C WebSocket</label>
<br>
<input id="radio2"type="radio"name="group1"onclick="updateUrl('/SpringSocketJs/sockjs/websocket');">
<label for="radio2">SockJS</label>
<div id="sockJsTransportSelect" style="visibility:hidden;">
SockJS transport:
<select onchange="updateTransport(this.value)">
<option value="all">all</option>
<option value="websocket">websocket</option>
<option value="xhr-polling">xhr-polling</option>
<option value="jsonp-polling">jsonp-polling</option>
<option value="xhr-streaming">xhr-streaming</option>
<option value="iframe-eventsource">iframe-eventsource</option>
<option value="iframe-htmlfile">iframe-htmlfile</option>
</select>
</div>
<div>
<button id="connect"onclick="connect();">Connect</button>
<button id="disconnect"disabled="disabled"onclick="disconnect();">Disconnect</button>
</div>
<div>
<textarea id="message"style="width:350px">Here is a message!</textarea>
</div>
<div>
<button id="echo"onclick="echo();"disabled="disabled">Echo message</button>
</div>
</div>
<div id="console-container">
<div id="console"></div>
</div>
</div>
</body>
</html>
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.