在一个项目中要使用WebSocket技术来实现服务器与浏览器实时通信交互,在网上也找了许多资料。为了防止以后忘记具体的使用过程,下面我把自己的使用过程和方法记录下来方便自己以后使用。
项目背景: 基于spring+spring MVC+mybatis框架的项目
1、jar包支持:
1. javax.websocket-api-1.1.jar
注意:因为在项目中使用了JSONObject的JSON工具,所以还需要导入如下包,否则会出现异常:java.lang.NoClassDefFoundError:org/apache/commons/lang/exception/NestableRuntimeException
json-lib-2.2.2-jdk15.jar
ezmorph-1.0.6.jar
commons-logging-1.1.1.jar
commons-lang-2.6.jar
commons-collections-3.2.1.jar
commons-beanutils-1.8.3.jar
2、编写服务端代码
MyWebSocketServer 类
import java.io.IOException;
import javax.websocket.EncodeException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import net.sf.json.JSONObject;
@ServerEndpoint(value = "/websocket") // 客户端访问地址:ws://[Server端的IP或域名]:[Server端口]/项目名/websocket
public class MyWebSocketServer {
private Logger logger = Logger.getLogger(MyWebSocketServer.class);
private Session session;
/**
* 连接建立后触发的方法
*/
@OnOpen
public void onOpen(Session session){
this.session = session;
logger.info("onOpen"+session.getId());
WebSocketMapUtil.put(session.getId(),this);
}
/**
* 连接关闭后触发的方法
*/
@OnClose
public void onClose(){
//从map中删除
WebSocketMapUtil.remove(session.getId());
logger.info("====== onClose:"+session.getId()+" ======");
}
/**
* 接收到客户端消息时触发的方法
*/
@OnMessage
public void onMessage(String params,Session session) throws Exception{
//获取服务端到客户端的通道
MyWebSocketServer myWebSocket = WebSocketMapUtil.get(session.getId());
logger.info("收到来自"+session.getId()+"的消息"+params);
String result = "收到来自"+session.getId()+"的消息"+params;
//返回消息给Web Socket客户端(浏览器)
myWebSocket.sendMessage(1,”成功!”,result);
}
/**
* 发生错误时触发的方法
*/
@OnError
public void onError(Session session,Throwable error){
logger.info(session.getId()+"连接发生错误"+error.getMessage());
error.printStackTrace();
}
public void sendMessage(int status,String message,Object datas) throws IOException{
JSONObject result = new JSONObject();
result.put("status", status);
result.put("message", message);
result.put("datas", datas);
this.session.getBasicRemote().sendText(result.toString());
}
}
WebSocketMapUtil 工具类
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class WebSocketMapUtil {
public static ConcurrentMap webSocketMap = new ConcurrentHashMap<>();
public static void put(String key, MyWebSocketServer myWebSocketServer){
webSocketMap.put(key, myWebSocketServer);
}
public static MyWebSocketServer get(String key){
return webSocketMap.get(key);
}
public static void remove(String key){
webSocketMap.remove(key);
}
public static Collection getValues(){
return webSocketMap.values();
}
}
3、前端代码
var websocket = null;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
alert("浏览器支持Websocket")
websocket = new WebSocket('ws://localhost:8080/oes/websocket');
} else {
alert('当前浏览器 Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function() {
alert("WebSocket连接发生错误")
setMessageInnerHTML("WebSocket连接发生错误");
};
//连接成功建立的回调方法
websocket.onopen = function() {
alert("WebSocket连接成功")
setMessageInnerHTML("WebSocket连接成功");
}
//接收到消息的回调方法
websocket.onmessage = function(event) {
alert("接收到消息的回调方法")
alert("这是后台推送的消息:"+event.data);
websocket.close();
alert("webSocket已关闭!")
}
//连接关闭的回调方法
websocket.onclose = function() {
setMessageInnerHTML("WebSocket连接关闭");
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
closeWebSocket();
}
//关闭WebSocket连接
function closeWebSocket() {
websocket.close();
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '
';
}