溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Springboot整合Websocket如何實現(xiàn)后端向前端主動推送消息

發(fā)布時間:2021-09-29 15:23:28 來源:億速云 閱讀:159 作者:柒染 欄目:開發(fā)技術(shù)

本篇文章為大家展示了Springboot整合Websocket如何實現(xiàn)后端向前端主動推送消息,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

在手機上相信都有來自服務器的推送消息,比如一些及時的新聞信息,這篇文章主要就是實現(xiàn)這個功能,只演示一個基本的案例。使用的是websocket技術(shù)。

一、什么是websocke

tWebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實現(xiàn)了客戶端與服務器全雙工通信,學過計算機網(wǎng)絡(luò)都知道,既然是全雙工,就說明了服務器可以主動發(fā)送信息給客戶端。這與我們的推送技術(shù)或者是多人在線聊天的功能不謀而合。

為什么不使用HTTP  協(xié)議呢?這是因為HTTP是單工通信,通信只能由客戶端發(fā)起,客戶端請求一下,服務器處理一下,這就太麻煩了。于是websocket應運而生。

下面我們就直接開始使用Springboot開始整合。以下案例都在我自己的電腦上測試成功,你可以根據(jù)自己的功能進行修改即可。

二、整合websocket

1、環(huán)境配置

Idea 2018專業(yè)版(已破解)

Maven 4.0.0

SpringBoot 2.2.2

websocket 2.1.3

jdk 1.8

下面我們新建一個普通的Springboot項目。

2、添加依賴

<dependencies>      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-web</artifactId>      </dependency>      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-test</artifactId>          <scope>test</scope>      </dependency>      <dependency>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-starter-websocket</artifactId>          <version>2.1.3.RELEASE</version>      </dependency>  </dependencies>

3、在application.properties文件修改端口號

一句話:server.port=8081

4、新建config包,創(chuàng)建WebSocketConfig類

1@Configuration 2public class WebSocketConfig { 3    @Bean 4    public ServerEndpointExporter serverEndpointExporter() { 5        return new ServerEndpointExporter(); 6    } 7}

5、新建service包,創(chuàng)建WebSocketServer類

@ServerEndpoint("/websocket/{sid}") @Component public class WebSocketServer {     static Log log= LogFactory.getLog(WebSocketServer.class);     //靜態(tài)變量,用來記錄當前在線連接數(shù)。應該把它設(shè)計成線程安全的。     private static int onlineCount = 0;     //concurrent包的線程安全Set,用來存放每個客戶端對應的MyWebSocket對象。     private static CopyOnWriteArraySet<WebSocketServer> webSocketSet             = new CopyOnWriteArraySet<WebSocketServer>();     //與某個客戶端的連接會話,需要通過它來給客戶端發(fā)送數(shù)據(jù)     private Session session;     //接收sid     private String sid="";     /**      * 連接建立成功調(diào)用的方法      */     @OnOpen     public void onOpen(Session session,@PathParam("sid") String sid) {         this.session = session;         webSocketSet.add(this);     //加入set中         addOnlineCount();           //在線數(shù)加1         log.info("有新窗口開始監(jiān)聽:"+sid+",當前在線人數(shù)為" + getOnlineCount());         this.sid=sid;         try {             sendMessage("連接成功");         } catch (IOException e) {             log.error("websocket IO異常");         }     }     /**      * 連接關(guān)閉調(diào)用的方法      */     @OnClose     public void onClose() {         webSocketSet.remove(this);  //從set中刪除         subOnlineCount();           //在線數(shù)減1         log.info("有一連接關(guān)閉!當前在線人數(shù)為" + getOnlineCount());     }     /**      * 收到客戶端消息后調(diào)用的方法      * @param message 客戶端發(fā)送過來的消息      */     @OnMessage     public void onMessage(String message, Session session) {         log.info("收到來自窗口"+sid+"的信息:"+message);         //群發(fā)消息         for (WebSocketServer item : webSocketSet) {             try {                 item.sendMessage(message);             } catch (IOException e) {                 e.printStackTrace();             }         }     }     @OnError     public void onError(Session session, Throwable error) {         log.error("發(fā)生錯誤");         error.printStackTrace();     }     //實現(xiàn)服務器主動推送     public void sendMessage(String message) throws IOException {         this.session.getBasicRemote().sendText(message);     }     //群發(fā)自定義消息     public static void sendInfo(String message,@PathParam("sid") String sid)          throws IOException {         log.info("推送消息到窗口"+sid+",推送內(nèi)容:"+message);         for (WebSocketServer item : webSocketSet) {             try {                 //這里可以設(shè)定只推送給這個sid的,為null則全部推送                 if(sid==null) {                     item.sendMessage(message);                 }else if(item.sid.equals(sid)){                     item.sendMessage(message);                 }             } catch (IOException e) {                 continue;             }         }     }     public static synchronized int getOnlineCount() {         return onlineCount;     }     public static synchronized void addOnlineCount() {         WebSocketServer.onlineCount++;     }     public static synchronized void subOnlineCount() {         WebSocketServer.onlineCount--;     }

6、新建controller包,創(chuàng)建Mycontroller類

@Controller public class MyController {     //頁面請求     @GetMapping("/socket/{cid}")     public ModelAndView socket(@PathVariable String cid) {         ModelAndView mav=new ModelAndView("/socket");         mav.addObject("cid", cid);         return mav;     }     //推送數(shù)據(jù)接口     @ResponseBody     @RequestMapping("/socket/push/{cid}")     public String pushToWeb(@PathVariable String cid,String message) {         try {             WebSocketServer.sendInfo(message,cid);         } catch (IOException e) {             e.printStackTrace();             return "推送失敗";         }         return "發(fā)送成功";     } }}

7、新建一個websocket.html頁面

<html> <head>     <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />     <script type="text/javascript">         var socket;         if (typeof (WebSocket) == "undefined") {             console.log("您的瀏覽器不支持WebSocket");         } else {             console.log("您的瀏覽器支持WebSocket");             //實現(xiàn)化WebSocket對象,指定要連接的服務器地址與端口  建立連接               socket = new WebSocket("ws://localhost:8081/websocket/1");             //打開事件               socket.onopen = function () {                 console.log("Socket 已打開");                 socket.send("這是來自客戶端的消息" + location.href + new Date());             };             //獲得消息事件               socket.onmessage = function (msg) {                 console.log(msg.data);             };             //關(guān)閉事件               socket.onclose = function () {                 console.log("Socket已關(guān)閉");             };             //發(fā)生了錯誤事件               socket.onerror = function () {                 alert("Socket發(fā)生了錯誤");             }         }     </script> </head> </html>

現(xiàn)在開發(fā)服務器和網(wǎng)頁就可以看到效果了。一般情況下Springboot2+Netty+Websocket的組合方式更加的常用一下。這個只是給出了一個基本的案例,你可以根據(jù)自己的需求進行更改。


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI