最近在做web项目的时候因为要不断的获取最新数据,ajax一直刷新数据实在是很消耗资源,所以采用了WebSocket进行推送数据到客户端。但是WebSocket也有劣势,那就是不支持低版本的IE浏览器。下面是spring boot初步整合WebSocket的例子。
先新建一个spring boot项目。
1.引入webSocket的包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.创建配置文件
@Configuration
public class WebsocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3.采用注解形式来编写websocket处理请求的类
@ServerEndpoint(value = "/socketServer/{userid}")
@Component
public class SocketServer {
private Session session;
private static Map<String, Session> sessionPool = new ConcurrentHashMap<>();
private static Map<String, String> sessionIds = new ConcurrentHashMap<>();
/**
* 用户连接时触发
*
* @param session session
* @param userid userid
*/
@OnOpen
public void open(Session session, @PathParam(value = "userid") String userid) {
this.session = session;
String id = session.getId();
Map<String, Object> userProperties = session.getUserProperties();
if (userProperties.size() > 0) {
Set<Map.Entry<String, Object>> entries = userProperties.entrySet();
for (Map.Entry<String, Object> entry : entries) {
System.out.println(entry.getKey() + "----" + entry.getValue());
}
}
System.out.println("id-----> " + id);
sessionPool.put(userid, session);
sessionIds.put(session.getId(), userid);
}
/**
* 收到信息时触发
*
* @param message message
*/
@OnMessage
public void onMessage(String message) {
System.out.println("当前发送人sessionid为" + session.getId() + "发送内容为" + message);
}
/**
* 连接关闭触发
*/
@OnClose
public void onClose() {
sessionPool.remove(sessionIds.get(session.getId()));
sessionIds.remove(session.getId());
}
/**
* 发生错误时触发
*
* @param session session
* @param error error
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
/**
* 信息发送的方法
*
* @param message message
* @param userId userId
*/
public void sendMessage(String message, String userId) {
Session s = sessionPool.get(userId);
//Session s = redisUtil.get(userId);
if (s != null) {
s.getAsyncRemote().sendText(message);
}
}
/**
* 获取当前连接数
*
* @return int
*/
public static int getOnlineNum() {
return sessionPool.size();
}
/**
* 获取在线用户名以---------隔开
*
* @return userId
*/
public String getOnlineUsers() {
StringBuilder users = new StringBuilder();
for (String key : sessionIds.keySet()) {
users.append(sessionIds.get(key)).append("---------");
}
return users.toString();
}
/**
* 信息群发
*
* @param msg msg
*/
public void sendAll(String msg) {
for (String key : sessionIds.keySet()) {
sendMessage(msg, sessionIds.get(key));
}
}
/**
* 多个人发送给指定的几个用户
*
* @param msg msg
* @param persons 用户数组
*/
public void sendMany(String msg, String[] persons) {
for (String userid : persons) {
sendMessage(msg, userid);
}
}
}
最后我们可以在spring boot工程中注入此类来给客户端推送消息。如果需要做分布式。推荐是在应用层来做分布式。因为session是不能持久化操作的。不能转化为json存储到redis中。
上面只是一个简单的例子。如果需要其他操作可以自行添加。