spring-boot-starter-websocket-01
一.简介
Websocket 是一个实现全双工的tcp眷属通信协议,最大的特点服务端可主动推送信息,使用场景:广告推送,统计数据主动推送,聊天等。
二. 核心成员介绍
API-DOC https://docs.spring.io/spring-framework/docs/current/javadoc-api/
1. Handler
功能:一些核心的操作驱动方法

WebSocketHandler
void afterConnectionEstablished(WebSocketSession);接入处理方法
void handleMessage(WebSocketSession, WebSocketMessage<?>);接收消息处理方法
void handleTransportError(WebSocketSession, Throwable);异常处理方法
void afterConnectionClosed(WebSocketSession, CloseStatus);断开处理方法
boolean supportsPartialMessages();是否支持部分消息处理
AbstractWebSocketHandler
handleMessage(WebSocketSession, WebSocketMessage<?>)一定程度的实现(分流了字节数据和二进制数据)
TextWebSocketHandler
protected void handleBinaryMessage(WebSocketSession, BinaryMessage)新增了二进制数据接收处理(拒绝二进制消息)
BinaryWebSocketHandler
protected void handleTextMessage(WebSocketSession, TextMessage)新增了字节数据接收处理(拒绝字节消息)

2. Session
功能: websocket会话对象存储

常用成员
WebSocketSession
实现了Closeable,定义了对session的基本操作
NativeWebSocketSession
定义了getNativeSession操作
AbstractWebSocketSession<T>
private T nativeSession 以聚合的方式集成了session实例
StandardWebSocketSession
定义了session关键字段
JettyWebSocketSession
定义了session关键字段

3. Message
功能:存储消息
WebSocketMessage<T>
T getPayload();返回消息负载
int getPayloadLength();返回消息负载字节长度
boolean isLast();消息是否是完整消息
AbstractWebSocketMessage<T>
private final T payload;
private final boolean last;定义了核心字段
TextMessage
将消息处理成String放入payload
BinaryMessage
将消息以字节形式放入payload
三. 搭建实例
1. pom导入

2. WebSocketSessionManager
public class WebSocketSessionManager {
/**
* 根据id存储会话对象
*/
private static Map<String, WebSocketSession> sessions = new HashMap<>();
/**
* 添加会话对象
* @param session
*/
public static void addSession(WebSocketSession session){
sessions.put(session.getId(),session);
}
/**
* 发送消息
*/
public static void sendMessage(List<String> userList, TextMessage msg,WebSocketSession userSession) throws Exception {
/*
用户列表不存在则全员广播
*/
if(Objects.isNull(userList)){
for(Map.Entry<String,WebSocketSession> entry : sessions.entrySet()){
if(!userSession.equals(entry.getValue())){
entry.getValue().sendMessage(msg);
}
}
return;
}
/*
通过用户列表进行分组多播
*/
userList.stream().filter(id->id!=null)
.forEach(id->{
WebSocketSession session = sessions.get(id);
if(Objects.isNull(session)){
return;
}
try {
session.sendMessage(msg);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
/**
* 会话移除
* @param session
* @throws IOException
*/
public static void removeAndClose(WebSocketSession session) throws IOException {
sessions.remove(session);
session.close();
}
}
3. 实现TextWebSocketHandler
@Slf4j
@Component
public class WebSocketHandler extends TextWebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
log.info("客户端接入》》》》"+ session.getClass());
WebSocketSessionManager.addSession(session); //添加客户端会话
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
log.info("===客户端发送testMessage===");
// 获得客户端传来的消息(全员广播)
WebSocketSessionManager.sendMessage(null,message,session);
}
@Override
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
// 实现方式对照handleTextMessage
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
//异常时触发
log.error("session: "+session+" exception: "+exception.getMessage());
super.handleTransportError(session,exception); //调用超类异常处理
WebSocketSessionManager.removeAndClose(session); //移除session
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// socket连接关闭后触发
log.info("断开连接》》》》"+ session.getClass());
WebSocketSessionManager.removeAndClose(session); //移除session
}
}
4. 配置
@Configuration
@EnableWebSocket //开启websocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private WebSocketHandler webSocketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry
.addHandler(webSocketHandler, "/msg") //指定处理器和Endpoint
.setAllowedOrigins("*"); //开放跨域
}
}