在這里小小推薦下我的個人博客
csdn:雷園的csdn博客
個人博客:雷園的個人博客
簡書:雷園的簡書
Springboot項目中如何使用WebSocket實現(xiàn)消息推送
首先,我們來說一下消息推送的應(yīng)用場景
1.我們現(xiàn)在在飯店吃飯,好多飯店都有掃碼點餐自助下單的服務(wù),那么后廚或者是前臺是如何收到我們下單的信息,并且能夠及時的進(jìn)行處理呢?
2.我們在網(wǎng)吧,你登錄英雄聯(lián)盟的時候,整個網(wǎng)吧總是會響起“坐在233號的玩家,是來自德瑪西亞的鉆石大神”。
3.還有等等一系列的推送服務(wù)。那么消息推送到底是如何實現(xiàn)的呢?我們今天就來小小的探究一番。
接下來我們進(jìn)入主題
1.首先我們需要在pom.xml中添加websocket依賴,打開pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.因為我們使用的是springboot項目,不使用配置文件,所以我們需要在項目啟動類同級目錄創(chuàng)建一個配置類WebSocketConfig.java
package com.ambow.springboot;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Component
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3.接下來就是編寫實現(xiàn)類WebSocket.java,通過該類對視圖層HTML、JSP進(jìn)行消息推送,當(dāng)然功能并不僅僅限制與此。
package com.ambow.springboot;
import groovy.util.logging.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.CopyOnWriteArraySet;
@Component
// 你的WebSocket訪問地址
@ServerEndpoint("/webSocket")
@Slf4j
public class WebSocket {
private Session session;
//定義Websocket容器,儲存session
private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();
//對應(yīng)前端的一些事件
//建立連接
@OnOpen
public void opOpen(Session session) {
this.session = session;
webSocketSet.add(this);
}
//關(guān)閉連接
@OnClose
public void onClose() {
webSocketSet.remove(this);
}
//接收消息
@OnMessage
public void onMessage(String message) {
}
//發(fā)送消息
public void sendMessage(String message) {
//遍歷儲存的Websocket
for (WebSocket webSocket : webSocketSet) {
//發(fā)送
try {
webSocket.session.getBasicRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
4.接下來我們需要定義在何時出發(fā)消息推送方法,一般我們將此類代碼放置在service業(yè)務(wù)邏輯層,例如:在飯店我們下單成功后,邏輯層接收到數(shù)據(jù)訪問層返回成功數(shù)據(jù)后,調(diào)用消息推送方法,將訂單信息等等所需數(shù)據(jù)推送至后廚或者是前臺。我在這里以訂單為例:OrderServiceImpl.java中創(chuàng)建訂單的方法, webSocket可以像注入Dao層一樣注入,因為在上面我們已經(jīng)進(jìn)行了bean配置。
@Autowired
private WebSocket webSocket;
@RequestMapping("/createOrder")
@ResponseBody
public String createOrder(HttpServletRequest request, HttpServletResponse response) {
//獲取cookie中的訂單號
String order_numberCookie = getorder_numberCookie(request);
long order_number;
if (order_numberCookie != null) {
order_number = Long.parseLong(order_numberCookie);
orderDao.createOrder(order_number);
webSocket.sendMessage("有新的訂單");
// 獲取名為"cart"的cookie
Cookie cookie = getCookie(request);
if (cookie != null) {
// 設(shè)置壽命為0秒
cookie.setMaxAge(0);
// 設(shè)置路徑
cookie.setPath("/");
// 設(shè)置cookie的value為null
cookie.setValue(null);
// 更新cookie
response.addCookie(cookie);
}
return "success";
}
return "error";
}
如此我們就將“有心的訂單”這條消息發(fā)送到了WebSocket.java中,那么在webSocket中就會將我們的消息推送到接收消息的客戶端。
那么接下來我們就看看在HTMl、JSP這類視圖中是如何接受推送來的消息的。webSocket.js
var websocket = null;
//瀏覽器是否支持
if ('WebSocket' in window) {
// 上面我們給webSocket定位的路徑
websocket = new WebSocket('ws://localhost:8080/webSocket');
} else {
alert('該瀏覽器不支持websocket!');
}
//建立連接
websocket.onopen = function (event) {
console.log('建立連接');
}
//關(guān)閉連接
websocket.onclose = function (event) {
console.log('連接關(guān)閉');
}
//消息來的時候的事件
websocket.onmessage = function (event) {
// 這里event.data就是我們從后臺推送過來的消息
console.log('收到消息:' + event.data);
// 在這里我們可以在頁面中放置一個音樂,例如“您有新的訂單了!”這樣的提示音
document.getElementById("newOrderMp3").play();
}
//發(fā)生錯誤時
websocket.onerror = function () {
alert('websocket通信發(fā)生錯誤!');
}
//窗口關(guān)閉時,Websocket關(guān)閉
window.onbeforeunload = function () {
websocket.close();
}
到現(xiàn)在,當(dāng)有人下單時,你就可以在網(wǎng)頁f12的控制臺中看到“收到消息:有新的訂單啦!”這樣的消息。如果你放置了音樂,那么你就可以聽到提示了。
結(jié)束語
1.webSocket的用途很廣泛,可以用來做簡單的消息推送,可以用來做一個即時的聊天通訊,新聞推送,公告發(fā)布等等。
2.非常感謝大家的關(guān)注,往后同樣,干貨不斷,大家多多支持關(guān)注我?。?!感謝???????。?!