前言
关于Springboot中WebSocket的介绍这里就不赘述了。网上还是有比较多的介绍。本文主要解决的问题是广播消息(某个主题的),特定用户的消息发送。废话不多说,开始我们的实现。
环境
这里只罗列核心的技术点。
jdk :1.8
maven :3.X
Spring boot:1.5.2.RELEASE
WebSocket:spring-boot-starter-websocket
前端引擎:thymeleaf
前端框架:org.webjars:jQuery,Bootstrap,websocket等
实现
socket核心配置容器
配置topic和服务端服务 ,注入session的bean以及监听。
package com.ricky.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
/**
* socket核心配置容器
*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");// /users 默认通知
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ricky-websocket").withSockJS();
}
@Bean
public SocketSessionRegistry SocketSessionRegistry(){
return new SocketSessionRegistry();
}
@Bean
public STOMPConnectEventListener STOMPConnectEventListener(){
return new STOMPConnectEventListener();
}
}
用户session记录类
用户session记录,用于销毁和存储以及获取使用。
package com.ricky.websocket;
import org.springframework.util.Assert;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* Created by baiguantao on 2017/8/4.
* 用户session记录类
*/
public class SocketSessionRegistry{
//this map save every session
//这个集合存储session
private final ConcurrentMap<String, Set<String>> userSessionIds = new ConcurrentHashMap();
private final Object lock = new Object();
public SocketSessionRegistry() {
}
/**
*
* 获取sessionId
* @param user
* @return
*/
public Set<String> getSessionIds(String user) {
Set set = (Set)this.userSessionIds.get(user);
return set != null?set: Collections.emptySet();
}
/**
* 获取所有session
* @return
*/
public ConcurrentMap<String, Set<String>> getAllSessionIds() {
return this.userSessionIds;
}
/**
* register session
* @param user
* @param sessionId
*/
public void registerSessionId(String user, String sessionId) {
Assert.notNull(user, "User must not be null");
Assert.notNull(sessionId, "Session ID must not be null");
Object var3 = this.lock;
synchronized(this.lock) {
Object set = (Set)this.userSessionIds.get(user);
if(set == null) {
set = new CopyOnWriteArraySet();
this.userSessionIds.put(user, (Set<String>) set);