1、什么是websocket?
WebSocket协议定义了一种web应用的新功能,它实现了服务器端和客户端的全双工通信。全双工通信即通信的双方可以同时发送和接收信息 的信息交互方式。它是继Java applets, XMLHttpRequest, Adobe Flash, ActiveXObject等使web应用更具交互性的新技术。
在实现连线过程中,浏览器和服务器通过TCP三次握手建立连接。 如果和服务器连接成功后,浏览器通过HTTP发送握手请求,如果服务器同意握手连接,客户端和服务端之后就能互相之间发送信息。HTTP只用于开始的握手,一旦成功建立握手连接,HTTP不会参与数据传输,使用TCP连接来传输数据。
2、以往和服务器交互的几种方式
轮询
长轮询就是客户端按照一个固定的时间定期向服务器发送请求,通常这个时间间隔的长度受到服务端的更新频率和客户端处理更新数据时间的影响。这种方式缺点很明显,就是浏览器要不断发请求到服务器以获取最新信息,造成服务器压力过大,占用宽带资源。
使用streaming AJAX
streaming ajax是一种通过ajax实现的长连接维持机制。主要目的就是在数据传输过程中对返回的数据进行读取,并且不会关闭连接。
iframe方式
iframe可以在页面中嵌套一个子页面,通过将iframe的src指向一个长连接的请求地址,服务端就能不断往客户端传输数据。
3、什么时候用websocket?
最适合websocket的web应用的就是那些客户端和服务器端需要高频繁、低延迟交换信息的应用。
4、如何使用websocket?
Spring提供了一个是适应于各种websocket引擎的websocket api,例如是Tomcat (7.0.47+)和GlassFish (4.0+),也适应于支持原生websocket的Jetty (9.0+)。而不同的浏览器对websocket的支持程度也有所不同,如果浏览器websocket不支持,那么可以用SocketJs代替websocket。
创建和配置WebSocketHandler
WebSocketHandler用于处理websocket的消息。
public class MyHandler extends TextWebSocketHandler { @Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
session.sendMessage(message);
} }
创建和配置HandshakeInterceptor
HandshakeInterceptor
用于处理握手前后的预处理工作。
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor { @Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
System.out.println("After Handshake");
super.afterHandshake(request, response, wsHandler, ex);
} @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);
}
}
同时配置spring-websocket.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket.xsd"> <websocket:handlers>
<websocket:mapping handler="myHandler" path="/myHandler"/>
<websocket:handshake-interceptors>
<bean class="org.springframework.samples.HandshakeInterceptor"></bean>
</websocket:handshake-interceptors>
</websocket:handlers>
<!--兼容低版本浏览器-->
<websocket:handlers>
<websocket:mapping handler="myHandler" path="/js/myHandler"/>
<websocket:handshake-interceptors>
<bean class="org.springframework.samples.HandshakeInterceptor"></bean>
</websocket:handshake-interceptors>
<websocket:sockjs />
</websocket:handlers> <bean id="myHandler" class="org.springframework.samples.MyHandler"></bean> </beans>
在页面上添加JavaScript
<script type="text/javascript" src="js/sockjs.min.js"></script>
<script type="text/javascript">
//websocket-demo是project name
var sock=null;
if (window['WebSocket']) {
sock= new WebSocket('ws://' + window.location.host+'/websocket-demo/myHandler');
}
else
sock= new SockJS('/websocket-demo/js/myHandler');//兼容低版本浏览器
sock.onopen = function() {
console.log('Opening');
sayHello();
};
sock.onmessage = function(e) {
alert('Received message: '+ e.data);
};
sock.onclose = function() {
console.log('Closing');
};
function sayHello() {
console.log('Sending Hello!');
sock.send("Hello!");
}
</script>
如果要兼容低版本浏览器,还要在web.xml添加
<async-supported>true</async-supported>
需要注意的地方:
1、应用服务器的版本,如果版本过低是不支持websocket的
2、JavaScript的websocket的url应该和spring-websocket.xml的<websocket:mapping path="">一致
3、要兼容低版本浏览器,要使用web3.0,还有必须在一个请求涉及的所有Servlet及Filter中都声明asyncSupported=true。