注意点:
1、Spring Framework从4.0版本开始支持websocket,示例代码使用的是4.1.3
2、SockJs是一个封装的WebSocket实现,可以支持低版本的IE浏览器。
3、SockJs+Spring-WebSocket时,由于SockJs与Spring WebSocket之间采用JSON通讯,需要引入jackson 2的相关jar包。
4、项目需要使用到Spring MVC。
具体代码实现(小例子):
1、Spring WebSocket配置类
package com.watcher.websocket.spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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 //配置类
@EnableWebSocket //声明支持websocket
public class WebSocketConfig implements WebSocketConfigurer{
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
//注册websocket实现类,指定参数访问地址;allowed-origins="*" 允许跨域
registry.addHandler(myHandler(), "/ws").addInterceptors(myHandshake()).setAllowedOrigins("*");
//允许客户端使用SockJS
registry.addHandler(myHandler(), "/sockjs/ws").addInterceptors(myHandshake()).withSockJS();
}
@Bean
public MyHandler myHandler(){
return new MyHandler();
}
@Bean
public MyHandshakeInterceptor myHandshake(){
return new MyHandshakeInterceptor();
}
}
2、Handler类实现(用于处理具体的消息)
package com.watcher.websocket.spring;
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;
//extending either TextWebSocketHandler orBinaryWebSocketHandler
public class MyHandler implements WebSocketHandler {
@Override
public void afterConnectionClosed(WebSocketSession arg0, CloseStatus arg1) throws Exception {
// TODO Auto-generated method stub
System.out.println("Connection closed..."+arg0.getRemoteAddress().toString());
}
@Override
public void afterConnectionEstablished(WebSocketSession arg0) throws Exception {
// TODO Auto-generated method stub
System.out.println("Connection established..."+arg0.getRemoteAddress().toString());
}
@Override
public void handleMessage(WebSocketSession arg0, WebSocketMessage<?> arg1) throws Exception {
// TODO Auto-generated method stub
try {
System.out.println("Req: "+arg1.getPayload());
TextMessage returnMessage = new TextMessage(arg1.getPayload()
+ " received at server");
arg0.sendMessage(returnMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void handleTransportError(WebSocketSession arg0, Throwable arg1) throws Exception {
// TODO Auto-generated method stub
if(arg0.isOpen()){
arg0.close();
}
System.out.println(arg1.toString());
System.out.println("WS connection error,close...");
}
@Override
public boolean supportsPartialMessages() {
// TODO Auto-generated method stub
return false;
}
}
3、握手拦截器实现(拦截器...)
package com.watcher.websocket.spring;
import java.util.Map;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
/**
*
* 类描述:握手拦截器
* com.watcher.websocket.spring MyHandshakeInterceptor
* Created by 78098 on 2016年11月15日.
* version 1.0
*/
public class MyHandshakeInterceptor extends HttpSessionHandshakeInterceptor{
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
// TODO Auto-generated method stub
System.out.println("After handshake "+request.getRemoteAddress().toString());
super.afterHandshake(request, response, wsHandler, ex);
}
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Map<String, Object> map) throws Exception {
// TODO Auto-generated method stub
System.out.println("Before handshake "+request.getRemoteAddress().toString());
return super.beforeHandshake(request, response, handler, map);
}
}
4、页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="./plugin/sockjs/sockjs-1.1.1.js"></script>
<script type="text/javascript">
var url = "192.168.120.37:8080/springMybatis";
var websocket = null;
if ('WebSocket' in window) {
websocket = new WebSocket("ws://" + url + "/ws");
} else {
websocket = new SockJS("http://" + url + "/sockjs/ws");
}
websocket.onopen = onOpen;
websocket.onmessage = onMessage;
websocket.onerror = onError;
websocket.onclose = onClose;
function onOpen(openEvent) {
document.getElementById("console").innerHTML = document.getElementById("console").innerHTML+ "OPEN<br/>";
}
function onMessage(event) {
document.getElementById("console").innerHTML = document.getElementById("console").innerHTML+ event.data+"<br/>";
}
function onError() {
}
function onClose() {
document.getElementById("console").innerHTML = document.getElementById("console").innerHTML+ "CLOSE<br/>";
}
function doSend() {
console.log(websocket.readyState);
if (websocket.readyState == SockJS.OPEN) {
var msg = document.getElementById("message").value;
websocket.send(msg);
} else {
alert("连接失败!");
}
}
function disconnect(){
if (websocket != null) {
websocket.close();
websocket = null;
}
}
function reconnect(){
if (websocket != null) {
websocket.close();
websocket = null;
}
if ('WebSocket' in window) {
websocket = new WebSocket("ws://" + url + "/ws");
} else {
websocket = new SockJS("http://" + url + "/sockjs/ws");
}
websocket.onopen = onOpen;
websocket.onmessage = onMessage;
websocket.onerror = onError;
websocket.onclose = onClose;
}
</script>
</head>
<body>
<div>
<button id="disconnect" οnclick="disconnect()">断开连接</button>
<button id="send" οnclick="doSend()">发送消息</button>
<button id="reconnect" οnclick="reconnect()">重新连接</button>
</div>
<div>
<textarea id="message" style="width: 350px">Here is a message!</textarea>
</div>
<div>日志信息:</div>
<p id="console" width="600px"></p>
</body>
</html>