java部分:vue
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.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CopyOnWriteArraySet; /** * @description:TODO * @author:xing.Li * @date:2019/8/26 10:02 */ @Component @ServerEndpoint("/websocket/{code}") //此注解至关于设置访问URL public class WebSocket { private Session session; 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="code")String code) { this.session = session; webSockets.add(this); sessionPool.put(code, session); Constants.WEBSOCKET = true;//定义常量 是否开启websocket链接 System.out.println("【websocket消息】有新的链接,总数为:"+webSockets.size()); } @OnClose public void onClose() { webSockets.remove(this); Constants.WEBSOCKET = false; System.out.println("【websocket消息】链接断开,总数为:"+webSockets.size()); } @OnMessage public void onMessage(String message) { System.out.println("【websocket消息】收到客户端消息:"+message); } // 此为广播消息 public void sendAllMessage(String message) { for(WebSocket webSocket : webSockets) { System.out.println("【websocket消息】广播消息:"+message); try { webSocket.session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } // 此为单点消息 public void sendOneMessage(String code, String message) { Session session = sessionPool.get(code); /*在发送数据以前先确认 session是否已经打开 使用session.isOpen() 为true 则发送消息 * 否则会报错:The WebSocket session [0] has been closed and no method (apart from close()) may be called on a closed session */ if (session != null && session.isOpen()) { try { session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } }
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * @description:TODO * @author:xing.Li * @date:2019/8/25 17:44 */ @Configuration public class WebSocketConfig {//打包部署到tomcat中须要删除此文件 /** * 注入ServerEndpointExporter, * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
此处为springboot自动执行代码 @Scheduled(fixedRate = 5 * 1000)//多少秒执行一次 @Async//异步执行 public void computerTableOnline() { if (Constants.WEBSOCKET) { R r = computerListService.queryList(Constants.COMPUTER_GROUP); if ("0".equals(r.get("code").toString()) && r.get("ComputerList") != null) { List<ComputerList> computerList = (List<ComputerList>) r.get("ComputerList"); String str = JSON.toJSONString(computerList); // List转json webSocket.sendOneMessage("computer", str);//websocket推送数据 } } }
最终要的固然是jar包了java
<!--websocket--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> <version>1.5.3.RELEASE</version> <type>pom</type> </dependency>
js部分:web
data(){} 中spring
created() { // 页面建立生命周期函数 this.initWebSocket() }, destroyed: function () { // 离开页面生命周期函数 this.websocketclose(); },
methods中json
initWebSocket: function () { // WebSocket与普通的请求所用协议有所不一样,ws等同于http,wss等同于https key你自定义的key var host = window.location.host; this.websock = new WebSocket("ws://" + host + "/websocket/key"); this.websock.onopen = this.websocketonopen; this.websock.onerror = this.websocketonerror; this.websock.onmessage = this.websocketonmessage; this.websock.onclose = this.websocketclose; }, websocketonopen: function () { console.log("WebSocket链接成功"); console.log("WebSocket正在发送实时数据......."); }, websocketonerror: function (e) { console.log("WebSocket链接发生错误"); }, websocketonmessage: function (e) { JSON.parse(e.data); //这个是收到后端主动推送的值 } }, websocketclose: function (e) { console.log("WebSocket链接断开"); }
实现思路:经过websocket长链接从后端主动推送数据,利用vue的双向绑定实现数据同步后端
注:由于数据的改变也会刷新表格上复选框的选中状态,本人思路为,element ui中有选中复选框的值得集合,判断复选框里面有没有值,有值的话就是在操做数据,这时中止websocket的链接,操做完成后,复选框值所在集合也就没有值了,这时再开启websocket链接,这样也有问题,可是算是实现了吧。。。。缓存
在此记录方便之后观看tomcat
固然上面的部分代码是忘记那位博主的了,时间过久找不到连接了,就不放原文连接了springboot
----------------------------------------------------------------------------------------------------------------------------------------------------------------websocket
更新:
最近打包发现了个问题,websocket放在tomcat中运行会报错,具体缘由忘了。。好像是说在tomcat8以上会替代spring管理bean因此删除WebSocketConfig这个配置bean的文件就能够正常运行了
----------------------------------------------------------------------------------------------------------------------------------------------------------------
更新:
需求又变了,说是让选中也能够进行实时刷新,又网上找了下,发现大佬写法:http://www.javashuo.com/article/p-risyvwhh-dn.html
其实element ui 官网就有写法,仍是要多看看文档-0.0-
官网是说
代码为
<!-- stripe--启用马纹线 border--启用边框 highlight-current-row--启用单选 sortable--启用排序--> <el-table ref="multipleTable" :data="tables.slice((currentPage-1)*pagesize,currentPage*pagesize)" stripe border highlight-current-row tooltip-effect="dark" style="width: 100%;font-size: 13px" :cell-style="{padding:'0px'}" @row-click="rowClick" :row-style="rowStyle" :row-class-name="rowClassName" @selection-change="handleSelectionChange" :row-key="getRowKeys"> <el-table-column sortable :reserve-selection="true" type="selection" width="55"></el-table-column> <el-table-column sortable prop="test" label="test" show-overflow-tooltip></el-table-column> <el-table-column sortable prop="test" label="test" show-overflow-tooltip></el-table-column> <el-table-column sortable prop="test" label="test" show-overflow-tooltip></el-table-column> <el-table-column sortable prop="test" label="testtest" show-overflow-tooltip></el-table-column> <el-table-column sortable prop="test" label="test" show-overflow-tooltip></el-table-column> </el-table>
须要加入代码已加粗加下划线 这个不能直接reserve-selection="true"这样写
会报错Invalid prop: type check failed for prop "reserveSelection". Expected Boolean, got String with value "true".
错误大体为须要一个boolean类型的参数,可是传入为String类型的须要加上 :reserve-selection="true"
还有要返回一个当前行标识
// 指定返回的行 getRowKeys(row){ return row.id; },
----------------------------------------------------------------------------------------------------------------------------------------------------------------
再更新,忽然发现一个问题,由于element ui 中
@selection-change="handleSelectionChange"
是获取复选框选中的行的全部值,当我选中时就会缓存进页面声明的集合或者对象中,若是这时websocket更新了tabledata中的值,这时缓存的值就成了旧数据,这样确定是不行的,那怎么办,看到这个大佬的博客,先贴出来 https://blog.csdn.net/qq_36537108/article/details/89261394 上面是这样说的 利用vue的ref属性和element中的 复选框属性
type="selection"
在按钮点击的时候获取当前复选框选中的值,这时点击按钮时就是当前的新数据这样就避免了出现旧数据
懒得打,复制过来吧,注意这个selection就是复选框呀
而后选中的是这样写的
this.$refs.multipleTable.selection
个人代码是这个逻辑,由于只有一个页面会用到实时刷新,因此其余页面就不用改了,而后就是在点击事件的开始就让
下面这个就是element ui 官网给出的选中复选框的那个@selection-change="handleSelectionChange"
注意这个 self 是 var self = this;
handleSelectionChange(val) { this.multipleSelection = val },
self.multipleSelection = this.$refs.multipleTable.selection;
直接替换掉旧的数据而后代码就不用有大改动