依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
config
package com.example.logicbackfrontback.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter;/** * 在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作, * 然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。HTML5 定 * 义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。 */@Configurationpublic class WebSocketConfig { /** * ServerEndpointExporter 作用 * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }}
model
package com.example.logicbackfrontback.model.webSocket;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@ServerEndpoint("/websocket")public class WebSocket { private Session session; private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>(); private String msg = "0"; @OnOpen public void onOpen(Session session) { this.session = session; webSockets.add(this); sendAllMessage(msg); } /** * 关闭调用方法 */ @OnClose public void onClose() { webSockets.remove(this); } @OnMessage public void onMessage(String msg) { } /** * 消息广播到前台 * * @param msg */ public void sendAllMessage(String msg) { for (WebSocket webSocket : webSockets) { try { webSocket.session.getBasicRemote().sendText(msg); } catch (Exception e) { e.printStackTrace(); } } }}
controller
package com.example.logicbackfrontback.controller;import com.example.logicbackfrontback.model.webSocket.WebSocket;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class ExportTxt { @Autowired private WebSocket websocket; @RequestMapping(value = "/test", method = RequestMethod.POST, produces = "application/json;charset=utf-8") public void test(){ String msg = ""; int a = 0; for(int i=0;i<6;i++){ msg = String.valueOf(a); websocket.sendAllMessage(msg); a=a+20; } }}
vue 前端
<template> <div> <el-progress :percentage="percentMsg"></el-progress> <el-button @click="test">开始上传</el-button> </div></template><script>export default { name: 'StartBack', props: ['mainData'], data () { return { percentMsg: 0 } }, mounted () { // WebSocket if ('WebSocket' in window) { this.websocket = new WebSocket('ws://localhost:8084/websocket') this.initWebSocket() } else { alert('当前浏览器 Not support websocket') } }, methods: { test () { this.$axios.post( 'test', {} ).then(data => { console.log('================================') // eslint-disable-next-line handle-callback-err }).catch(error => { }) }, initWebSocket () { // 连接错误 this.websocket.onerror = this.setErrorMessage // 连接成功 this.websocket.onopen = this.setOnopenMessage // 收到消息的回调 this.websocket.onmessage = this.setOnmessageMessage // 连接关闭的回调 this.websocket.onclose = this.setOncloseMessage // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = this.onbeforeunload }, setErrorMessage () { console.log( 'WebSocket连接发生错误 状态码:' + this.websocket.readyState ) }, setOnopenMessage () { // console.log("WebSocket连接成功 状态码:" + this.websocket.readyState); }, setOnmessageMessage (event) { console.log(false) // 服务器推送的消息 console.log('服务端返回:' + event.data) // percentMsg就是绑定的进度值 this.percentMsg = parseInt(event.data) if (this.percentMsg === 100) { // 如果进度是100 dialog框就隐藏 this.dialogPortVisible = false } }, setOncloseMessage () { // console.log("WebSocket连接关闭 状态码:" + this.websocket.readyState); }, onbeforeunload () { this.closeWebSocket() }, closeWebSocket () { this.websocket.close() }, // format函数是和进度条组件绑定的 具体可查看element-ui组件官网进度条 format (percentage) { return percentage === 100 ? '满' : `${percentage}%` } }}</script>