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