服务端代码:
第一步:初始化websocket 【推荐带sessionid 到websocket 作为参数】 ${sessionId}
function openWebSocket(){
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
console.info(window.location.host);
ws = new WebSocket("ws://"+window.location.host+"/visualizationWebSocket.do?sessionId="+${sessionId});
} else {
ws = new SockJS("http://"+window.location.host+"/wechat/sockjs/visualizationWebSocket/info?type=mall");
}
ws.onopen = function () {
console.info("当网络连接建立时触发该事件");
};
//这个事件是接受后端传过来的数据
ws.onmessage = function (event) {
//根据业务逻辑解析数据
console.info("onmessage 当websocket接收到服务器发来的消息的时触发的事件,也是通信中最重要的一个监听事件。msg.data\n" +
"websocket还定义了一个readyState属性,这个属性可以返回websocket所处的状态:"+event.data);
};
ws.onclose = function (event) {
console.info("关闭该websocket链接");
};
}
第二步:初始化websocket,会自动调用 俩个类中的方法
第一个方法 : VisualizationHandshakeInterceptor.java 类中的beforeHandshake ,在这里可以获得从前端的传过来的参数。并且做拦截,校验路径是否是正常的
package com.zzw.wechat.interfaces.websocket;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
//回话拦截器
public class VisualizationHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
//获取请求参数,首先我们要获取HttpServletRequest对象才能获取请求参数;当ServerHttpRequset的层次结构打开后其子类可以获取到我们想要的http对象,那么就简单了。
//我这里是把获取的请求数据绑定到session的map对象中(attributes)
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
System.out.println("beforeHandshake: ");
String sessionId = servletRequest.getParameter("sessionId");
if(sessionId!=null){
attributes.put("sessionId",sessionId);
}
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);
}
}
第二个方法:
VisualizationWebSocketHandler.java 类中的 afterConnectionEstablished 方法,在方法中可以获得参数。
package com.zzw.wechat.interfaces.websocket;
import net.sf.json.JSONObject;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class VisualizationWebSocketHandler extends TextWebSocketHandler {
private static final Map<String,WebSocketSession> sessions = new HashMap<String, WebSocketSession>();
private static final Map<String,Thread> threads = new HashMap<String, Thread>();
private Thread polingVisualization = null;
//用户标识
private static final String CLIENT_ID = "sessionId";
/* @Autowired
private IVisualizationService visualizationService;*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
Object sessionId = session.getAttributes().get("sessionId");
System.out.println("afterConnectionEstablished=谁连接了.="+sessionId);
if(sessionId!=null){
sessions.put(sessionId.toString(),session);
Iterator iterator= sessions.keySet().iterator();
while(iterator.hasNext()){
String key = iterator.next().toString();
System.out.println("map key===="+key);
System.out.println("map value===="+sessions.get(key));
}
}
super.afterConnectionEstablished(session);
}
//afterConnectionClosed 通信关闭调用的方法
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
System.out.println("---关闭连接");
Object sessionId = session.getAttributes().get("sessionId");
if(sessionId!=null){
sessions.remove(sessionId.toString());
}
/*Thread thread = threads.get(session.getId());
if(thread != null){
thread.interrupt();
try {
thread.join();
threads.remove(session.getId());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
sessions.remove(session.getId());
sessions.remove(CLIENT_ID);
polingVisualization = null;
try {
super.afterConnectionClosed(session, status);
} catch (Exception e) {
}*/
}
// 作用一:客户端返回消息,服务端接收的方法
//作用二:把接收消息,返回到前端
@Override
protected void handleTextMessage(WebSocketSession session,
TextMessage message) throws Exception {
String payload = message.getPayload();
System.out.println("payload接收的信息===="+payload);
JSONObject payloadJson = JSONObject.fromObject(payload);
String sessionId=payloadJson.get("sessionId").toString();
TextMessage returnMessage = new TextMessage(payloadJson.toString());
WebSocketSession sessionaa = sessions.get(sessionId);
sessionaa.sendMessage(returnMessage);
sessions.remove(sessionId);
/* System.out.println("handleTextMessage: \n"+session.getId());*/
/*super.handleTextMessage(session, message);
Thread thread = threads.get(session.getId());
if(thread == null){
WebSocketSession sessi = sessions.get(session.getId());
if(sessi == null){
sessions.put(session.getId(),session);
} else {
session = sessi;
}
final WebSocketSession localSession = session;
final TextMessage localMessage = message;
}*/
}
}
客户端代码:
第三步:客户端建立连接通信 MyClient.java 可直接拿去用
package com.zzw.wechat.interfaces.wechat;
import javax.websocket.ClientEndpoint;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import org.apache.log4j.Logger;
@ClientEndpoint
public class MyClient {
private static Logger logger = Logger.getLogger(MyClient.class);
private Session session;
@OnOpen
public void open(Session session) {
logger.info("Client WebSocket is opening...");
this.session = session;
}
@OnMessage
public void onMessage(String message) {
logger.info("Server send message: " + message);
}
@OnClose
public void onClose() {
logger.info("Websocket closed");
}
public void send(String message) {
this.session.getAsyncRemote().sendText(message);
}
}
第四步:客户端发送消息给服务端【客户端响应的方法,然后通过myclient 给服务端接收消息】
@RequestMapping(value = "/sendMsg")
@ResponseBody
public WebResultInfo sendMsg(@RequestBody Map<String,Object> map){
try {
//给服务端发送消息
System.out.println(map.get("sessionId"));
JSONObject json = new JSONObject();
json.put("rsult","客户端内容");
json.put("sessionId",map.get("sessionId"));
WebSocketContainer container = ContainerProvider.getWebSocketContainer(); // 获取WebSocket连接器,其中具体实现可以参照websocket-api.jar的源码,Class.forName("org.apache.tomcat.websocket.WsWebSocketContainer");
String uri = "ws://localhost:8099/visualizationWebSocket.do";
MyClient client = new MyClient();
Session mysession = container.connectToServer(client, new URI(uri)); // 连接会话
mysession.getBasicRemote().sendText(json.toString()); // 发送文本消息
mysession.close();
}catch (Exception e){
e.printStackTrace();
}
return WebResultInfo.success();
}
【第四步:注,当客户端发送消息给服务端,会调用VisualizationWebSocketHandler.java 类中的 afterConnectionEstablished 方法】,然后 afterConnectionEstablished 会相应给前端的 onmessage 方法。
ws.onmessage = function (event) {
//根据业务逻辑解析数据
console.info("onmessage 当websocket接收到服务器发来的消息的时触发的事件,也是通信中最重要的一个监听事件。msg.data\n" +
"websocket还定义了一个readyState属性,这个属性可以返回websocket所处的状态:"+event.data);
};