1.导入maven依赖
<!-- websocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>
2.创建类 HandshakeInterceptor 继承 HttpSessionHandshakeInterceptor
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception { /**
* 在拦截器内强行修改websocket协议,将部分浏览器不支持的 x-webkit-deflate-frame 扩展修改成
* permessage-deflate
*/
if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
}
String jspCode = ((ServletServerHttpRequest) request).getServletRequest().getParameter("jspCode");
if (jspCode != null) {
attributes.put("jspCode", jspCode);
} else {
return false;
}
return true;
} @Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
}
3.创建类 MyWebSocketConfig 继承 WebMvcConfigurerAdapter 并实现 WebSocketConfigurer
@Component
@EnableWebMvc
@EnableWebSocket
public class MyWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
@Resource
MyWebSocketHandler handler; @Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// TODO Auto-generated method stub
registry.addHandler(handler, "/websocket").addInterceptors(new HandshakeInterceptor());
registry.addHandler(handler, "/websocket/sockjs").addInterceptors(new HandshakeInterceptor()).withSockJS();
}
}
4.创建类 MyWebSocketHandler 实现 WebSocketHandler
@Component
public class MyWebSocketHandler implements WebSocketHandler { public static final Map<String, WebSocketSession> userSocketSessionMap; static {
userSocketSessionMap = new HashMap<String, WebSocketSession>();
} @Override
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
// TODO Auto-generated method stub
String jspCode = session.getId() + "-" + (String) session.getHandshakeAttributes().get("jspCode"); if (userSocketSessionMap.get(jspCode) == null) {
System.out.println("添加会话:" + jspCode);
userSocketSessionMap.put(jspCode, session);
}
} @Override
public void handleMessage(WebSocketSession session,
WebSocketMessage<?> message) throws Exception {
// TODO Auto-generated method stub
session.sendMessage(message);
} @Override
public void handleTransportError(WebSocketSession session,
Throwable exception) throws Exception {
// TODO Auto-generated method stub
if (session.isOpen()) {
session.close();
}
Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap.entrySet().iterator();
// 移除Socket会话
while (it.hasNext()) {
Entry<String, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
userSocketSessionMap.remove(entry.getKey());
System.out.println("Socket会话已经移除:用户ID:" + entry.getKey());
break;
}
}
} @Override
public void afterConnectionClosed(WebSocketSession session,
CloseStatus closeStatus) throws Exception {
// TODO Auto-generated method stub
System.out.println("Websocket:" + session.getId() + "已经关闭");
Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap.entrySet().iterator();
// 移除Socket会话
while (it.hasNext()) {
Entry<String, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
userSocketSessionMap.remove(entry.getKey());
System.out.println("Socket会话已经移除:用户ID:" + entry.getKey());
break;
}
}
} @Override
public boolean supportsPartialMessages() {
// TODO Auto-generated method stub
return false;
}
}
5.前段使用
<!-- websocket -->
<script type="text/javascript">
$(function() { var jspCode = "${user.userId}"; var websocket;
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/ebcrawler/websocket?jspCode=" + jspCode);
} else if ('MozWebSocket' in window) {
websocket = new MozWebSocket("ws://localhost:8080/ebcrawler/websocket?jspCode=" + jspCode);
} else {
websocket = new SockJS("http://localhost:8080/ebcrawler/websocket/sockjs?jspCode=" + jspCode);
} websocket.onopen = function(event) {
$(".commonMsg").each(function() {
$(this).html($(this).html() + "已连接<br/>")
});
};
websocket.onmessage = function(event) {
var data = event.data;
var type = data.substring(0, data.indexOf("-"));
var msg = data.substring(data.indexOf("-") + 1);
if (type == "1") {
$("#doneMsg").html($("#doneMsg").html() + msg + "<br/>");
} else if (type == "2") {
$("#doingMsg").html(msg + "<br/>");
} else if (type == "3") {
$("#errorMsg").html(msg + "<br/>" + $("#errorMsg").html());
} else { } };
websocket.onerror = function(event) {
$(".commonMsg").each(function() {
$(this).html($(this).html() + "websocket发生错误<br/>")
});
};
websocket.onclose = function(event) {
$(".commonMsg").each(function() {
$(this).html($(this).html() + "已关闭<br/>")
});
};
});
</script>
6.后端使用
//websocket发给前端
Iterator<Entry<String, WebSocketSession>> it = MyWebSocketHandler.userSocketSessionMap.entrySet().iterator();
// 发给同一userId的客户端
while (it.hasNext()) { final Entry<String, WebSocketSession> entry = it.next();
String keyUserId = entry.getKey().substring(entry.getKey().indexOf("-") + 1);
WebSocketSession session = entry.getValue();
if (session.isOpen() && keyUserId.equals(userId)) {
try {
if (session.isOpen()) {
synchronized(session) {
entry.getValue().sendMessage(new TextMessage(msg));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:当多线程发送消息时,同一个WebSocketSession一次只能发送条消息,所以需要用synchronize将session锁住
还没有评论呢,快来抢沙发~