1、简介
作为下一代的Web标准,HTML5拥有许多引人注目的新特性,如 Canvas、本地存储、多媒体编程接口、WebSocket等等。这其中有“Web的 TCP”之称的 WebSocket格外吸引开发人员的注意。WebSocket的出现使得浏览器提供对 Socket的支持成为可能,从而在浏览器和服务器之间提供了一个基于TCP连接的双向通道。Web开发人员可以非常方便地使用WebSocket构建实时 web 应用,开发人员的手中从此又多了一柄神兵利器。
Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别频繁的应用尚能相安无事,但是对于那些实时要求比较高的应用来说,比如说在线游戏、在线证券、设备监控、新闻在线播报、RSS订阅推送等等,当客户端浏览器准备呈现这些信息的时候,这些信息在服务器端可能已经过时了。
所以保持客户端和服务器端的信息同步是实时 Web应用的关键要素,对 Web开发人员来说也是一个难题。在 WebSocket规范出来之前,开发人员想实现这些实时的Web应用,不得不采用一些折衷的方案,其中最常用的就是轮询(Polling)和 Comet 技术,而Comet技术实际上是轮询技术的改进,又可细分为两种实现方式,一种是长轮询机制,一种称为流技术。
Html5 WebSocket 设计出来的目的就是要取代轮询和 Comet技术,使客户端浏览器具备像 C/S架构下桌面系统的实时通讯能力。浏览器通过JavaScript向服务器发出建立 WebSocket连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP连接直接交换数据。因为 WebSocket连接本质上就是一个TCP连接,所以在数据传输的稳定性和数据传输量的大小方面,和轮询以及Comet技术比较,具有很大的性能优势。
但是鉴于web socket 对浏览器要求比较高,为了解决这个问题,推出了sockJS,SockJS是一个JavaScript库,提供跨浏览器javascript的API,创建了一个低延迟、全双工的浏览器和web服务器之间通信通道。
2、相关环境要求
Spring4.0.6(要选择4.0+),tomcat7.0.55版本,JDK1.7。
3、具体代码
(以下代码亲测可用!)
(1)web.xml:
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">
用来测试WebSocket基础上推送的功能
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
true
encoding
UTF-8
forceEncoding
true
encodingFilter
/*
org.springframework.web.context.ContextLoaderListener
org.springframework.web.util.IntrospectorCleanupListener
dispatcher
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:dispatcher-servlet.xml
1
true
dispatcher
/
30
testSocket.jsp
(2) dispatcher-servlet.xml
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">
(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 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
-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
WebSocket/SockJS Echo Sample (Adapted from Tomcat's echo sample)#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;
}
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;
}
Seems your browser doesn't supportJavascript!Websockets
rely on Javascript being enabled. Please enable
Javascript and reload this page!
W3C WebSocket
SockJS
SockJS transport:
all
websocket
xhr-polling
jsonp-polling
xhr-streaming
iframe-eventsource
iframe-htmlfile
Connect
Disconnect
Here is a message!
Echo message
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。