SpringBoot整合WebSocket
一个前后端分离的项目,后端如何主动向前端发送消息呢? websocket
什么是websocket:https://www.ruanyifeng.com/blog/2017/05/websocket.html
一、导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
二、配置类
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
三、服务类
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}") // 接口路径 ws://localhost:8081/webSocket/xxx;
public class WebSocket {
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
// 存放每个用户的连接 CopyOnWriteArraySet是线程安全的set
private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
// 用来存在线连接数
private static Map<String,Session> sessionPool = new HashMap<String,Session>();
// 连接成功时调用
@OnOpen
public void onOpen(Session session, @PathParam(value="userId")String userId) {
try {
this.session = session;
webSockets.add(this);
sessionPool.put(userId, session);
} catch (Exception e) {
}
}
// 关闭连接时调用
@OnClose
public void onClose() {
try {
webSockets.remove(this);
} catch (Exception e) {
}
}
// 收到客户端消息时调用
@OnMessage
public void onMessage(String message) {
...
}
// 发生错误时调用
@OnError
public void onError(Session session, Throwable error) {
...
}
// 给所有用户发送消息
public void sendAllMessage(String message) {
for(WebSocket webSocket : webSockets) {
try {
if(webSocket.session.isOpen()) {
webSocket.session.getAsyncRemote().sendText(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 给某个用户发送消息
public void sendOneMessage(String userId, String message) {
Session session = sessionPool.get(userId);
if (session != null && session.isOpen()) {
try {
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
...
}
}
}
// 给多个用户发送消息
public void sendMoreMessage(String[] userIds, String message) {
for(String userId:userIds) {
Session session = sessionPool.get(userId);
if (session != null && session.isOpen()) {
try {
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
...
}
}
}
}
}
四、发送消息
@SpringBootTest
public class WebSocketTest {
@Autowired
private WebSocket webSocket;
@Test
public void test01() {
webSocket.sendAllMessage("666");
}
}
五、前端接收
在vue的methods中添加以下方法
initWebSocket: function () { // 建立连接
// WebSocket与普通的请求所用协议有所不同,ws和http类似,wss和https类似
var user = localStorage.getItem("user");
var url = "ws://localhost:8081/websocket/"+user.userId;
this.websock = new WebSocket(url);
this.websock.onopen = this.websocketonopen;
this.websock.send = this.websocketsend;
this.websock.onerror = this.websocketonerror;
this.websock.onmessage = this.websocketonmessage;
this.websock.onclose = this.websocketclose;
},
// 连接成功后调用
websocketonopen: function () {
...
},
// 发生错误时调用
websocketonerror: function (e) {
...
},
// 给后端发消息时调用
websocketsend: function (e) {
...
},
// 接收消息时调用
websocketonmessage: function (e) {
...
},
// 关闭连接时调用
websocketclose: function (e) {
...
}
然后在页面加载完成之前,如mounted中初始化websocket:
this.initWebSocket()
并且在关闭页面时调用websocketclose,如在destroyed中添加:
this.websocketclose();