隨記:在springboot中websocket的使用

我現在有兩種方法

第一種:使用java封裝的這個包下的javax.websocket.*

先配置這個配置類

import com.alibaba.nacos.common.utils.CollectionUtils;
import org.springframework.stereotype.Component;import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import java.util.List;
import java.util.Map;@Component
public class WebSocketServerConfig extends ServerEndpointConfig.Configurator {@Overridepublic boolean checkOrigin(String originHeaderValue) {//todo webSocket的 過濾 權限校驗return true;}@Overridepublic void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {Map<String, List<String>> parameterMap = request.getParameterMap();List<String> erpList = parameterMap.get("erp");if(!CollectionUtils.isEmpty(erpList)){sec.getUserProperties().put("erp", erpList.get(0));}}}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

?創建一個socket

前端應該怎么連接呢

?

第二種:使用spring自定義的websocket + Disruptor。

?先定義這個配置

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Resourceprivate PictureEditHandler pictureEditHandler;@Resourceprivate WsHandshakeInterceptor wsHandshakeInterceptor;@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {// websocketregistry.addHandler(pictureEditHandler, "/ws/picture/edit").addInterceptors(wsHandshakeInterceptor).setAllowedOrigins("*");}
}

再配置攔截器

/*** WebSocket 攔截器,建立連接前校驗*/
@Slf4j
@Component
public class WsHandshakeInterceptor implements HandshakeInterceptor {@Resourceprivate UserService userService;@Resourceprivate PictureService pictureService;@Resourceprivate SpaceService spaceService;@Resourceprivate SpaceUserAuthManager spaceUserAuthManager;/*** 建立連接前要校驗* @param request* @param response* @param wsHandler* @param attributes 給Session會話設置屬性* @return* @throws Exception*/@Overridepublic boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {if (request instanceof ServletServerHttpRequest) {HttpServletRequest httpServletRequest = ((ServletServerHttpRequest) request).getServletRequest();// 從請求中獲取用戶信息String pictureId = httpServletRequest.getParameter("pictureId");if (StrUtil.isBlank(pictureId)){log.info("缺少圖片參數,拒絕握手");return false;}// 獲取當前登入用戶User loginUser = userService.getLoginUser(httpServletRequest);if (ObjUtil.isEmpty(loginUser)){log.info("用戶未登錄,拒絕握手");return false;}// 校驗用戶是否有編輯當前圖片的權限Picture picture = pictureService.getById(pictureId);if (ObjUtil.isEmpty(picture)){log.info("圖片不存在,拒絕握手");return false;}Long spaceId = picture.getSpaceId();Space space =null;if (spaceId != null){space= spaceService.getById(spaceId);if (ObjUtil.isEmpty(space)){log.info("圖片所在空間不存在,拒絕握手");return false;}if (space.getSpaceType() != SpaceTypeEnum.TEAM.getValue()){log.info("圖片所在空間不是團隊空間,拒絕握手");return false;}}List<String> permissionList = spaceUserAuthManager.getPermissionList(space, loginUser);if (!permissionList.contains(SpaceUserPermissionConstant.PICTURE_EDIT)){log.info("用戶沒有編輯圖片的權限,拒絕握手");return false;}// 設置用戶登入信息等屬性到 WebSocket 會話中attributes.put("user", loginUser);attributes.put("userId", loginUser.getId());attributes.put("pictureId", Long.valueOf(pictureId)); // 記得轉換為 Long 類型}return true;}@Overridepublic void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {}
}

?再寫這個disrupter的配置 這個東西就像一個工廠一樣,但是不是啊。它可以根據消費者的消息類型來調用對應的方法。

/**
*disruptor 配置*/
@Configuration
public class PictureEditEventDisruptorConfig {@Resourceprivate PictureEditEventWorkHandler pictureEditEventWorkHandler;@Bean("pictureEditEventDisruptor")public Disruptor<PictureEditEvent> messageModelRingBuffer() {// ringBuffer 的大小int bufferSize = 1024 * 256;Disruptor<PictureEditEvent> disruptor = new Disruptor<>(PictureEditEvent::new,bufferSize,ThreadFactoryBuilder.create().setNamePrefix("pictureEditEventDisruptor").build());// 設置消費者disruptor.handleEventsWithWorkerPool(pictureEditEventWorkHandler);// 開啟 disruptordisruptor.start();return disruptor;}
}

消費者 舉的一個例子?

/*** (消費者) 這只是一個例子*/
@Slf4j
@Component
public class PictureEditEventWorkHandler implements WorkHandler<PictureEditEvent> {@Resource@Lazyprivate PictureEditHandler pictureEditHandler;@Resourceprivate UserService userService;@Overridepublic void onEvent(PictureEditEvent event) throws Exception {PictureEditRequestMessage pictureEditRequestMessage = event.getPictureEditRequestMessage();WebSocketSession session = event.getSession();User user = event.getUser();Long pictureId = event.getPictureId();// 獲取到消息類別String type = pictureEditRequestMessage.getType();PictureEditMessageTypeEnum pictureEditMessageTypeEnum = PictureEditMessageTypeEnum.valueOf(type);// 調用對應的消息處理方法switch (pictureEditMessageTypeEnum) {case ENTER_EDIT:pictureEditHandler.handleEnterEditMessage(pictureEditRequestMessage, session, user, pictureId);break;case EDIT_ACTION:pictureEditHandler.handleEditActionMessage(pictureEditRequestMessage, session, user, pictureId);break;case EXIT_EDIT:pictureEditHandler.handleExitEditMessage(pictureEditRequestMessage, session, user, pictureId);break;default:PictureEditResponseMessage pictureEditResponseMessage = new PictureEditResponseMessage();pictureEditResponseMessage.setType(PictureEditMessageTypeEnum.ERROR.getValue());pictureEditResponseMessage.setMessage("消息類型錯誤");pictureEditResponseMessage.setUser(userService.getUserVO(user));session.sendMessage(new TextMessage(JSONUtil.toJsonStr(pictureEditResponseMessage)));}}
}

生產者的例子使用方法

/***生產者*/
@Component
@Slf4j
public class PictureEditEventProducer {@ResourceDisruptor<PictureEditEvent> pictureEditEventDisruptor;public void publishEvent(PictureEditRequestMessage pictureEditRequestMessage, WebSocketSession session, User user, Long pictureId) {RingBuffer<PictureEditEvent> ringBuffer = pictureEditEventDisruptor.getRingBuffer();// 獲取可以生成的位置long next = ringBuffer.next();PictureEditEvent pictureEditEvent = ringBuffer.get(next);pictureEditEvent.setSession(session);pictureEditEvent.setPictureEditRequestMessage(pictureEditRequestMessage);pictureEditEvent.setUser(user);pictureEditEvent.setPictureId(pictureId);// 發布事件ringBuffer.publish(next);}/*** 優雅停機*/@PreDestroypublic void close() {pictureEditEventDisruptor.shutdown(); // 默認處理完全部事件,再關閉}
}

最后就是處理websocket的方法里面是發送消息的所有方法和實現,

/***  WebSocket處理器*/
@Component
public class PictureEditHandler extends TextWebSocketHandler {@Resourceprivate PictureEditEventProducer pictureEditEventProducer;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/87514.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/87514.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/87514.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

技術文章大綱:SpringBoot自動化部署實戰

技術文章大綱&#xff1a;SpringBoot自動化部署實戰 概述 自動化部署的背景與意義SpringBoot在現代化部署中的優勢常見自動化部署工具與方案概覽&#xff08;Jenkins、Docker、K8s等&#xff09; 環境準備 基礎工具要求&#xff1a;JDK、Maven/Gradle、Git服務器環境配置&a…

FastAdmin按鈕類功能全解析 class 屬性定義不同的交互行為

在 FastAdmin 中&#xff0c;超鏈接的 class 屬性用于定義不同的交互行為和樣式。以下是常見 class 配置的用途和區別&#xff1a; btn-dialog 用于觸發彈出對話框行為。點擊帶有此 class 的鏈接或按鈕時&#xff0c;FastAdmin 會自動加載指定的 URL 內容并在模態框中顯示。通…

python3字典對象實現解析

文章目錄 前言Raymond的方案字典結構字典創建字典插入插入空字典PyDictKeysObject的創建設置索引存儲entry 插入非空字典調整大小字典查找聯合字典插入 字典查詢字典刪除 前言 本來以為python字典的實現就是一個哈希表的普通實現&#xff0c;所以在學習基本類型時沒去仔細研究…

Word2Vec介紹

前言 當今的大語言模型非常智能&#xff0c;但是你有沒有想過這些事情&#xff1a; 機器是怎么理解“國王”和“王后”之間的關系&#xff1f; “貓”和“狗”是怎么在 AI 中“相似以及區分”的&#xff1f; 文本又是怎么變成模型能讀懂的數字&#xff1f; 這一切&#xf…

Rsync+sersync實現數據實時同步(小白的“升級打怪”成長之路)

目錄 一、rsync部署 push推數據 1、編寫rsync配置文件 2、備份測試 3、檢驗結果 二、rsyncsersync 實現數據實時同步 1、安裝sersync服務 2、檢驗結果 pull拉取數據 1、編寫rsync配置文件 2、檢驗結果 三、腳本編寫 1、客戶端腳本編寫 2、服務器腳本編寫 一、rsy…

用 python 開發一個可調用工具的 AI Agent,實現電腦配置專業評價

在人工智能時代&#xff0c;AI Agent憑借其強大的任務處理能力&#xff0c;逐漸成為開發人員手中的得力工具。今天&#xff0c;我們就來一起動手&#xff0c;用Python打造一個能夠調用工具的AI Agent&#xff0c;實現根據電腦信息對電腦配置進行專業評價的功能。 一、項目創建…

WSL 安裝使用和常用命令

參考官方使用說明&#xff1a; https://learn.microsoft.com/zh-cn/windows/wsl/ 安裝wsl: wsl --install --no-distribution --no-distribution&#xff1a;安裝 WSL 時不要安裝分發版 更新 wsl: wsl --update 設置wsl 默認版本&#xff1a; wsl --set-default-version <…

720全景VR拍攝制作實戰教程

720全景VR拍攝制作實戰教程 720全景VR拍攝制作是近年來興起的一種沉浸式影像制作技術。它通過多角度拍攝&#xff0c;并將畫面拼接成一個全景視角&#xff0c;使觀眾獲得身臨其境的觀看體驗。本教程將帶你從準備階段到拍攝階段&#xff0c;再到后期處理階段&#xff0c;一步步…

什么真正的云原生開發?如何區別本地開發后部署到云端?

以下是關于云原生開發的深度解析&#xff0c;以及與本地開發后遷移上云的本質區別&#xff1a; 一、真正的云原生開發&#xff1a;從理念到實踐的全面革新 1. 定義與核心思想 云原生開發是一種以云計算能力為核心的架構設計和開發方法論&#xff0c;其本質是讓應用從誕生之初…

從代碼學習深度學習 - 詞的相似性和類比任務 PyTorch版

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言加載預訓練詞向量TokenEmbedding 類詳解預訓練詞向量簡介 (GloVe)具體含義總結建議應用預訓練詞向量詞相似度knn 函數get_similar_tokens 函數相似詞查找示例詞類比get_analogy 函數詞類比任務…

ubuntu 22.04 安裝部署elk(elasticsearch/logstash/kibana) 7.10.0詳細教程

安裝部署elk7.10.0詳細教程 一、安裝jdk 11環境二、安裝elasticsearch 7.10.0三、安裝kibana 7.10.0四、安裝logstash 7.10.0五、安裝ik7.10.0分詞六、開啟安全功能1. 開啟用戶名密碼登錄2. 開啟es安全加密通信3. 開啟Kibana安全功能 七、注意事項和常見錯誤八、其它操作及命令…

技術文章: 基板的吸水率

PCB基板或覆銅板的吸水率是一個重要的性能指標&#xff0c;它衡量了覆銅板在特定條件下&#xff08;通常是浸水后&#xff09;吸收水分的能力&#xff0c;通常用指定條件下吸水后與吸水前相比&#xff0c;質量增加的百分比來表示。當材料暴露扎起在潮濕空氣中或浸沒在水中時其抵…

九日集訓第三天

目錄 搜索旋轉排序數組 搜索旋轉排序數組|| 尋找旋轉排序中的數組最小值 爬樓梯 斐波那契數 第N個泰波那契數 差的絕對值為K的數對數目 猜數字 拿硬幣 山峰數組的峰頂索引 搜索旋轉排序數組 class Solution { public:int search(vector<int>& nums, int t…

CppCon 2017 學習:folly::Function A Non-copyable Alternative to std::function

你說的內容是關于 C 中 可調用類型&#xff08;Callable Types&#xff09; 的基礎知識&#xff0c;我幫你理清并補充理解。 Callable Types&#xff08;可調用類型&#xff09;簡介 C 中任何可以用 () 括號操作符“調用”的對象&#xff0c;都叫做 可調用類型。典型包括&…

PyTorch 中Tensor常用數據結構(int, list, numpy array等)互相轉換和實戰示例

在 PyTorch 中&#xff0c;tensor 是一種強大且靈活的數據結構&#xff0c;可以與多種 Python 常用數據結構&#xff08;如 int, list, numpy array 等&#xff09;互相轉換。下面是詳細解釋和代碼示例&#xff1a; 1. Tensor ? int / float 轉為 int / float&#xff08;前提…

計算機網絡與數據通信基礎

第一章 計算機網絡概述 1. 計算機網絡的核心概念 1.1 定義 將 地理分散 的、具有 獨立處理能力 的計算機系統&#xff08;主機/Host&#xff09;&#xff0c;通過 傳輸介質 與 網絡設備 互連&#xff0c;在 網絡協議 和 軟件 支持下實現 資源共享 與 數據通信 的系統。 關鍵術…

【統計術語】

文章目錄 基礎概念術語基期與現期增長量與增長率環比與同比 比重術語平均數術語特殊增長術語其他常用術語 基礎概念術語 基期與現期 基期&#xff1a;作為基礎參照的時期&#xff0c;一般指過去的時間 現期&#xff1a;與基期對比的時期&#xff0c;一般指現在的時間 示例&am…

XXE(XML外部實體注入)詳解

目錄 一、XXE漏洞簡介 二、XML詳解 (一) XML文檔結構 1. 文檔聲明 2. XML文檔類型定義&#xff08;DTD&#xff09; 3. XML文檔元素 4. XML文檔示例 三、XXE漏洞類型 四、XXE漏洞挖掘技巧 五、XXE漏洞危害 (一) 文件讀取 (二) 內網探測 1. 端口探測 2. 主機存活探…

深入解析JVM字節碼執行引擎

JVM 字節碼執行引擎。它是 JVM 核心組件之一&#xff0c;負責實際執行加載到內存中的字節碼指令。你可以將它想象成 JVM 的“CPU”。 核心職責&#xff1a; 加載待執行的字節碼&#xff1a; 從方法區&#xff08;元空間&#xff09;獲取已加載類的方法字節碼。創建和管理棧幀…

華為OD機試-MELON的難題-DFS(JAVA 2025A卷)

題意是從N快雨花石中找出最少拿出雨花石的塊數&#xff0c;使得雨花石可以均分&#xff0c;直接使用dfs解決此類組合問題 package com.example.demo.bean;import java.util.Arrays; import java.util.LinkedList; import java.util.Scanner;public class YuHuaStone {public s…