第一步pom.xml 引用
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
第二步建立SpringWebSocketConfig
/**
* @Description: 实现WebSocketConfigurer接口,重写registerWebSocketHandlers方法,这是一个核心实现方法,配置websocket入口,允许访问的域、注册Handler、SockJs支持和拦截器。
* @Param:
* @return:
* @Author: mufeng
* @Date: 2019/12/4
*/
@Configuration
@EnableWebSocket
public class SpringWebSocketConfig implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// 注册自定义消息处理,消息路径为`/websocket/socketServer`
//registry.addHandler注册和路由的功能,当客户端发起websocket连接,把/path交给对应的handler处理,而不实现具体的业务逻辑,可以理解为收集和任务分发中心。
//setAllowedOrigins(String[] domains),允许指定的域名或IP(含端口号)建立长连接,如果只允许自家域名访问,这里轻松设置。如果不限时使用"*"号,如果指定了域名,则必须要以http或https开头。
//addInterceptors,顾名思义就是为handler添加拦截器,可以在调用handler前后加入我们自己的逻辑代码。
registry.addHandler(webSocketHandler(),"/websocket/socketServer").addInterceptors(new SpringWebSocketHandlerInterceptor()).setAllowedOrigins("*");
registry.addHandler(webSocketHandler(), "/sockjs/socketServer").addInterceptors(new SpringWebSocketHandlerInterceptor()).setAllowedOrigins("*").withSockJS();
}
@Bean
public TextWebSocketHandler webSocketHandler(){
return new SpringWebSocketHandler();
}
}
第三步建立自己Handler SpringWebSocketHandler 继承TextWebSocketHandler
@Service
public class SpringWebSocketHandler extends TextWebSocketHandler {
private org.slf4j.Logger logger = LoggerFactory.getLogger(SpringWebSocketHandler.class);
/**
* 连接用户
*/
private static final ConcurrentHashMap<String, WebSocketSession> users;
static {
users = new ConcurrentHashMap<String, WebSocketSession>();
}
public SpringWebSocketHandler() {
}
/**
* 连接成功时候,会触发页面上onopen方法
*/
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
session.getAttributes().put("org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT", 200L);
String identification = session.getUri().getQuery();//这个位置取值是因为前端传值是url?value
//session.getAttributes().get("key");;//这个位置取值是因为前端传值是url?key=value
if (users.contains(identification)) {
WebSocketSession removeSession = users.get(identification);
if (removeSession.isOpen()) {
removeSession.close();
}
}
users.put(identification, session);
}
/**
* 关闭连接时触发
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
closeUser(session);
}
/**
* js调用websocket.send时候,会调用该方法
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String identification = session.getUri().getQuery();
try {
JSONObject json = JSONObject.fromObject(message.getPayload());
assort(identification, json);
} catch (Exception e) {
}
super.handleTextMessage(session, message);
}
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
closeUser(session);
}
public boolean supportsPartialMessages() {
return false;
}
/***
* @Description: 逻辑处理
* @Param:
* @return:
* @Author: mufeng
* @Date: 2019/12/4
*/
public void assort(String identification, JSONObject json) throws ParseException {
if (json.getString("type").equals("xxxxx")) {
typeQuotation(identification, json);
}
}
private void typeQuotation(String identification, JSONObject json) {
try {
//逻辑处理
} catch (Exception e) {
e.printStackTrace();
}
}
private void closeUser(WebSocketSession session) throws Exception {
String identification = session.getUri().getQuery();
if (session.isOpen()) {
session.close();
}
users.remove(identification);
// System.out.println("离线用户"+identification);
// System.out.println("剩余在线用户"+users.size());
}
/**
* 给某个用户发送消息
*
* @param key
* @param message
*/
public void sendMessageToUser(String key, TextMessage message) {
WebSocketSession user = users.get(key);
if (!CommonUtils.isEmpty(user)) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 给所有在线用户发送消息
*
* @param message
*/
public void sendMessageToUsers(TextMessage message) {
Set<String> keys = users.keySet();
for (String key : keys) {
WebSocketSession user = users.get(key);
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static ConcurrentHashMap<String, WebSocketSession> getUsers() {
return users;
}
}
第四步建立拦截器
/**
* WebSocket拦截器
* @author WANG
*
*/
public class SpringWebSocketHandlerInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
// TODO Auto-generated method stub
super.afterHandshake(request, response, wsHandler, ex);
}
}
第五步 Controller 主动调用
@Autowired
SpringWebSocketHandler socket;
public void sendMessageRefreshTradeRecord() {
JSONObject js = new JSONObject();
js.put("type","refresh");
TextMessage message = new TextMessage(js.toJSONString());
socket.sendMessageToUsers(message);
}