spring-boot-starter-websocket-01
一.簡介
????????Websocket?是一個(gè)實(shí)現(xiàn)全雙工的tcp眷屬通信協(xié)議,最大的特點(diǎn)服務(wù)端可主動(dòng)推送信息,使用場景:廣告推送,統(tǒng)計(jì)數(shù)據(jù)主動(dòng)推送,聊天等。
二. 核心成員介紹
????????API-DOC?https://docs.spring.io/spring-framework/docs/current/javadoc-api/
1. Handler
????????????功能:一些核心的操作驅(qū)動(dòng)方法

? ? ???
WebSocketHandler
?void afterConnectionEstablished(WebSocketSession);接入處理方法
?void handleMessage(WebSocketSession, WebSocketMessage<?>);接收消息處理方法
void handleTransportError(WebSocketSession, Throwable);異常處理方法
void afterConnectionClosed(WebSocketSession, CloseStatus);斷開處理方法
boolean supportsPartialMessages();是否支持部分消息處理
AbstractWebSocketHandler
handleMessage(WebSocketSession, WebSocketMessage<?>)一定程度的實(shí)現(xiàn)(分流了字節(jié)數(shù)據(jù)和二進(jìn)制數(shù)據(jù))
TextWebSocketHandler?
?protected void handleBinaryMessage(WebSocketSession, BinaryMessage)新增了二進(jìn)制數(shù)據(jù)接收處理(拒絕二進(jìn)制消息)
BinaryWebSocketHandler
protected void handleTextMessage(WebSocketSession, TextMessage)新增了字節(jié)數(shù)據(jù)接收處理(拒絕字節(jié)消息)

2.?Session
????功能:?websocket會(huì)話對(duì)象存儲(chǔ)

常用成員
WebSocketSession
實(shí)現(xiàn)了Closeable,定義了對(duì)session的基本操作
NativeWebSocketSession
定義了getNativeSession操作
AbstractWebSocketSession<T>
private T nativeSession?以聚合的方式集成了session實(shí)例
StandardWebSocketSession
定義了session關(guān)鍵字段
JettyWebSocketSession
?定義了session關(guān)鍵字段

3.?Message
????功能:存儲(chǔ)消息
WebSocketMessage<T>?
T getPayload();返回消息負(fù)載
int getPayloadLength();返回消息負(fù)載字節(jié)長度
boolean isLast();消息是否是完整消息
AbstractWebSocketMessage<T>? ? ? ?
private final T payload;
private final boolean last;定義了核心字段
TextMessage
將消息處理成String放入payload
BinaryMessage
將消息以字節(jié)形式放入payload
三. 搭建實(shí)例
1.?????pom導(dǎo)入

2.?????WebSocketSessionManager
public class WebSocketSessionManager {
? ?/**
? ? * 根據(jù)id存儲(chǔ)會(huì)話對(duì)象
? ? */
? ?private static Map<String, WebSocketSession> sessions = new HashMap<>();
? ?/**
? ? * 添加會(huì)話對(duì)象
? ? * @param session
? ? */
? ?public static void addSession(WebSocketSession session){
? ? ? ?sessions.put(session.getId(),session);
? ?}
? ?/**
? ? * 發(fā)送消息
? ? */
? ?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;
? ? ? ?}
? ? ? ?/*
? ? ? ? ? ?通過用戶列表進(jìn)行分組多播
? ? ? ? */
? ? ? ?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);
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?});
? ?}
? ?/**
? ? * 會(huì)話移除
? ? * @param session
? ? * @throws IOException
? ? */
? ?public static void removeAndClose(WebSocketSession session) throws IOException {
? ? ? ?sessions.remove(session);
? ? ? ?session.close();
? ?}
}
?
3.?????實(shí)現(xiàn)TextWebSocketHandler
@Slf4j
@Component
public class WebSocketHandler extends TextWebSocketHandler {
? ?@Override
? ?public void afterConnectionEstablished(WebSocketSession session) throws Exception {
? ? ? ?log.info("客戶端接入》》》》"+ session.getClass());
? ? ? ?WebSocketSessionManager.addSession(session); ?//添加客戶端會(huì)話
? ?}
? ?@Override
? ?protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
? ? ? ?log.info("===客戶端發(fā)送testMessage===");
? ? ? ?// 獲得客戶端傳來的消息(全員廣播)
? ? ? ?WebSocketSessionManager.sendMessage(null,message,session);
? ?}
? ?@Override
? ?protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
? ? ? ?// 實(shí)現(xiàn)方式對(duì)照handleTextMessage
? ?}
? ?@Override
? ?public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
? ? ? ?//異常時(shí)觸發(fā)
? ? ? ?log.error("session: "+session+" exception: "+exception.getMessage());
? ? ? ?super.handleTransportError(session,exception); //調(diào)用超類異常處理
? ? ? ?WebSocketSessionManager.removeAndClose(session); //移除session
? ?}
? ?@Override
? ?public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
? ? ? ?// socket連接關(guān)閉后觸發(fā)
? ? ? ?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("*"); //開放跨域
? ?}
}
?
????????