Springboot项目中如何使用WebSocket实现消息推送
首先,我们来说一下消息推送的应用场景
1.我们现在在饭店吃饭,好多饭店都有扫码点餐自助下单的服务,那么后厨或者是前台是如何收到我们下单的信息,并且能够及时的进行处理呢?
2.我们在网吧,你登录英雄联盟的时候,整个网吧总是会响起“坐在233号的玩家,是来自德玛西亚的钻石大神”。
3.还有等等一系列的推送服务。那么消息推送到底是如何实现的呢?我们今天就来小小的探究一番。
接下来我们进入主题
1.首先我们需要在pom.xml中添加websocket依赖,打开pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.因为我们使用的是springboot项目,不使用配置文件,所以我们需要在项目启动类同级目录创建一个配置类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.接下来就是编写实现类WebSocket.java,通过该类对视图层HTML、JSP进行消息推送,当然功能并不仅仅限制与此。
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<>();
//对应前端的一些事件
//建立连接
@OnOpen
public void opOpen(Session session) {
this.session = session;
webSocketSet.add(this);
}
//关闭连接
@OnClose
public void onClose() {
webSocketSet.remove(this);
}
//接收消息
@OnMessage
public void onMessage(String message) {
}
//发送消息
public void sendMessage(String message) {
//遍历储存的Websocket
for (WebSocket webSocket : webSocketSet) {
//发送
try {
webSocket.session.getBasicRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
4.接下来我们需要定义在何时出发消息推送方法,一般我们将此类代码放置在service业务逻辑层,例如:在饭店我们下单成功后,逻辑层接收到数据访问层返回成功数据后,调用消息推送方法,将订单信息等等所需数据推送至后厨或者是前台。我在这里以订单为例:OrderServiceImpl.java中创建订单的方法, webSocket可以像注入Dao层一样注入,因为在上面我们已经进行了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) {
// 设置寿命为0秒
cookie.setMaxAge(0);
// 设置路径
cookie.setPath("/");
// 设置cookie的value为null
cookie.setValue(null);
// 更新cookie
response.addCookie(cookie);
}
return "success";
}
return "error";
}
如此我们就将“有心的订单”这条消息发送到了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('建立连接');
}
//关闭连接
websocket.onclose = function (event) {
console.log('连接关闭');
}
//消息来的时候的事件
websocket.onmessage = function (event) {
// 这里event.data就是我们从后台推送过来的消息
console.log('收到消息:' + event.data);
// 在这里我们可以在页面中放置一个音乐,例如“您有新的订单了!”这样的提示音
document.getElementById("newOrderMp3").play();
}
//发生错误时
websocket.onerror = function () {
alert('websocket通信发生错误!');
}
//窗口关闭时,Websocket关闭
window.onbeforeunload = function () {
websocket.close();
}
到现在,当有人下单时,你就可以在网页f12的控制台中看到“收到消息:有新的订单啦!”这样的消息。如果你放置了音乐,那么你就可以听到提示了。
结束语