页面实时数据监听
頁面實時數據監(jiān)聽
數據更新頁面數據自動同步-多端
需求
無需手動點擊刷新頁面數據實時同步更新
實現想法一 定時器setInterval+watch
setInterval(() => {let _that = this;setTimeout(function () {_that.getlist(); //加載數據函數 自己的方法console.log("刷新" + new Date());}, 0);}, 1000);watch,它可以用來監(jiān)測Vue實例上的數據變動于是發(fā)現比較浪費性能并沒有達到我想要的預期效果
實現想法二 ajax的長輪詢
Ajax輪詢:客戶端是按照規(guī)定時間像服務端發(fā)送請求,前一次請求完成后,無論有無結果返回,規(guī)定時間之后下一次請求又會發(fā)出
Ajax長輪詢:當服務端收到客戶端發(fā)來的請求后,服務端不會直接進行響應,而是先將這個請求掛起,然后判斷服務器端數據是否有更新。如果有更新,則進行響應,如果一直沒有數據,則到達一定的時間限制(服務器端設置)才返回。 客戶端JavaScript響應處理函數會在處理完服務器返回的信息后,再次發(fā)出請求,重新建立連接。既把循環(huán)放到了服務端
啟動類上開啟異步 @EnableAsync@RequestMapping("/async") @RestController public class AsyncRequestDemo {@Autowiredprivate AsyncRequestService asyncRequestService;@GetMapping("/value")public String getValue() {String msg = null;Future<String> result = null;try{result = asyncRequestService.getValue();msg = result.get(10, TimeUnit.SECONDS);}catch (Exception e){e.printStackTrace();}finally {if (result != null){result.cancel(true);}}return msg;}@PostMapping("/value")public void postValue(String msg) {asyncRequestService.postValue(msg);} }@Service public class AsyncRequestService {private String msg = null;@Asyncpublic Future<String> getValue() throws InterruptedException {while (true){synchronized (this){if (msg != null){String resultMsg = msg;msg = null;return new AsyncResult(resultMsg);}}Thread.sleep(100);}}public synchronized void postValue(String msg) {this.msg = msg;} }這里是根據 msg 是否變化判斷是否響應返回@EnableAsync 開啟異步 @Sync 標記異步方法 Future 用于接收異步返回值 result.get(10, TimeUnit.SECONDS); 阻塞,超時獲取結果 Future.cancel() 中斷線程于是發(fā)現在多端中判斷服務器端數據是否有更新自己發(fā)現比較困難
實現想法三 websocket
收到客戶端消息后既對數據請求響應,數據的實時同步性比較好,
<!-- websocket --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency> /*** 前后端交互的類實現消息的接收推送(自己發(fā)送給自己)** @ServerEndpoint(value = "/ws/one") 前端通過此URI和后端交互,建立連接*/ @Slf4j @ServerEndpoint(value = "/ws/one/{userid}",encoders = { EncoderClassVo.class }) @Component public class OneWebSocket {/*** 與某個客戶端的連接對話,需要通過它來給客戶端發(fā)送消息*/private Session session;/*** 標識當前連接客戶端的用戶名*/private String userid;/*** 用于存所有的連接服務的客戶端,這個對象存儲是安全的*/private static ConcurrentHashMap<String,OneWebSocket> webSocketSet = new ConcurrentHashMap<>();// websocket 不能注入( @Autowired )private static VdataService vdataService;@Autowiredpublic void setVdataService(VdataService vdataService) {OneWebSocket.vdataService = vdataService;}/*** 記錄當前在線連接數*/ // private static AtomicInteger onlineCount = new AtomicInteger(0);/*** 連接建立成功調用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam(value = "userid")String userid) {this.session = session;this.userid = userid;// userid是用來表示唯一客戶端,如果需要指定發(fā)送,需要指定發(fā)送通過userid來區(qū)分webSocketSet.put(userid,this); // onlineCount.incrementAndGet(); // 在線數加1log.info("有新連接加入:用戶id,{},當前在線人數為:{}",this.userid, webSocketSet.size());}/*** 連接關閉調用的方法*/@OnClosepublic void onClose(Session session) { // onlineCount.decrementAndGet(); // 在線數減1webSocketSet.remove(this.userid);log.info("有一連接關閉:{},用戶id,{},當前在線人數為:{}", session.getId(),this.userid, webSocketSet.size());}/*** 收到客戶端消息后調用的方法** @param message 客戶端發(fā)送過來的消息*/@OnMessagepublic void onMessage(String message) throws ExecutionException, InterruptedException {// 你的業(yè)務邏輯JSONObject obj = JSONUtil.parseObj(message);String userid = obj.get("userid").toString();String page = obj.get("page").toString();String size = obj.get("size").toString();String isend = obj.get("isend").toString();System.err.println(obj);Future<Object> vData = vdataService.getlistVData(Integer.parseInt(userid), page, size, Integer.parseInt(isend));log.info("服務端 收到 客戶端 [{}]的消息:{}", userid, message);// 你的業(yè)務邏輯this.sendMessage(ResultDTO.success(vData.get()), userid);}@OnErrorpublic void onError(Throwable error) {webSocketSet.remove(this.userid);log.error("發(fā)生錯誤");error.printStackTrace();}/*** 服務端發(fā)送消息給客戶端*/private void sendMessage(ResultDTO message, String userid) {System.err.println("userid "+userid);try {log.info("服務端 給 客戶端[{}]發(fā)送消息{}", userid, JSONUtil.parseObj(message));webSocketSet.get(userid).session.getBasicRemote().sendObject(message);} catch (Exception e) {log.error("服務端發(fā)送消息給客戶端失敗:{}", e);}} }發(fā)現服務端發(fā)送消息給客戶端發(fā)送消息發(fā)送的object類型解析不了
需要配置解析類
在有數據操作的地方只需向服務端發(fā)送消息即可 new OneWebSocket().onMessage(msg);
于是實現了自己想要的功能,以此記錄
《新程序員》:云原生和全面數字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結
- 上一篇: 利用七牛云实现简单的图床
- 下一篇: 鞍点计算