<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
package cc.datebook.socketSpring;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import javax.servlet.http.HttpSession;
import java.util.Map;
/**
* @author wong
* @description 前端页面与后台通信握手拦截器, 可用于完善定向发送信息功能。
*/
@Component
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
private static final String SESSION_USER = "user";
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
}
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
HttpSession session = serverHttpRequest.getServletRequest().getSession();
if (session != null) {
attributes.put(SESSION_USER, session.getAttribute(SESSION_USER));
}
}
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
}
package cc.datebook.socketSpring
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.ApplicationContext
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
import org.springframework.web.socket.server.standard.ServerEndpointExporter
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketHandler(), "/webSocket/spring").addInterceptors(new HandshakeInterceptor()).setAllowedOrigins("*")
registry.addHandler(new SocketHandler(), "/sockJs/webSocket").addInterceptors(new HandshakeInterceptor()).withSockJS()
}
}
package cc.datebook.socketSpring;
import cc.datebook.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author wong
* @description webSocket处理类
*/
@Component
public class SocketHandler implements WebSocketHandler {
private static final Logger logger = LoggerFactory.getLogger(SocketHandler.class);
private static final Map<Integer, WebSocketSession> users = new HashMap<>();
private static final String SESSION_USER = "user";
/**
* 在WebSocket协商成功后调用,并且打开WebSocket连接准备使用
* @param webSocketSession
* @throws Exception 异常
*/
@Override
public void afterConnectionEstablished(WebSocketSession webSocketSession)throws IOException {
logger.info("成功建立连接");
Integer userId = getUserId(webSocketSession);
if (userId != null) {
users.put(userId, webSocketSession);
webSocketSession.sendMessage(new TextMessage("成功建立socket连接"));
}
}
/**
* 处理收到的webSocketMessage
*
* @param webSocketSession
* @param webSocketMessage
* @throws Exception
*/
@Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) {
logger.info(webSocketSession+":"+webSocketMessage.getPayload());
}
/**
* 处理来自底层WebSocket消息传输的错误
* @param webSocketSession
* @param throwable 错误
* @throws Exception 异常
*/
@Override
public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
if (webSocketSession.isOpen()) {
webSocketSession.close();
}
users.remove(getUserId(webSocketSession));
}
/**
* 在网络套接字连接关闭后或在传输错误发生后调用。
* 尽管从技术上讲,会话可能仍然是开放的,但取决于底层实现,在这一点上发送消息是不鼓励的,而且很可能不会成功。
* @param webSocketSession webSocketSession
* @param closeStatus closeStatus
* @throws Exception 异常
*/
@Override
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
if (webSocketSession.isOpen()) {
webSocketSession.close();
}
users.remove(getUserId(webSocketSession));
System.out.println("安全退出了系统");
}
/**
* WebSocketHandler是否处理部分消息
* @return 标志
*/
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
* 发送信息给指定用户
* @param userId
* @param message
* @return
*/
public static boolean sendMessageToUser(Integer userId, String message) {
if (users.get(userId) == null) {
return false;
}
WebSocketSession session = users.get(userId);
if (!session.isOpen()) {
return false;
}
try {
session.sendMessage(new TextMessage(message));
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 广播信息
* @param message
* @return
*/
public static boolean sendMessageToAllUsers(String message) {
boolean allSendSuccess = true;
Set<Integer> clientIds = users.keySet();
WebSocketSession session = null;
for (Integer clientId : clientIds) {
try {
session = users.get(clientId);
if (session.isOpen()) {
session.sendMessage(new TextMessage(message));
}
} catch (IOException e) {
e.printStackTrace();
allSendSuccess = false;
}
}
return allSendSuccess;
}
/**
* 获取用户id
* @param session
* @return
*/
private Integer getUserId(WebSocketSession session) {
try {
User userBean = (User) session.getAttributes().get(SESSION_USER);
return userBean.getId();
} catch (Exception e) {
return null;
}
}
}
require(["jquery","formUtil"], function ($) {
var url = 'ws://localhost:8090/项目名/webSocket/spring';
var ws = new WebSocket(url);
ws.onopen = function(e){
};
ws.onmessage = function(e) {
alert(e.data);
};
ws.onerror = function(e) {
alert(e);
};
$('body').one('DOMNodeRemoved','#start-help',function (e) {
ws.close();
});
$('#help-submit').on('click',function () {
var formData = $('#help-form').serializeJson();
ws.send(JSON.stringify(formData));
}) ;
});