日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

页面实时数据监听

發(fā)布時間:2025/3/21 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 页面实时数据监听 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

頁面實時數據監(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類型解析不了
需要配置解析類

public class EncoderClassVo implements Encoder.Text<ResultDTO>{@Overridepublic void init(EndpointConfig config) {// TODO Auto-generated method stub}@Overridepublic void destroy() {// TODO Auto-generated method stub}//如果你傳遞的是一個類,則使用如下寫法@Overridepublic String encode(ResultDTO resultDTO) throws EncodeException {return JSONUtil.toJsonStr(resultDTO);} } destroyed() {this.websock.close() //離開路由之后斷開websocket連接},created() {this.initWebSocket();},initWebSocket(){ //初始化weosocketconsole.log("初始化weosocket");const wsuri = "ws://127.0.0.1:80/ws/one/"+this.userid;this.websock = new WebSocket(wsuri);this.websock.onopen = this.websocketonopen;this.websock.onmessage = this.websocketonmessage;this.websock.onerror = this.websocketonerror;this.websock.onclose = this.websocketclose;},websocketonopen(){ //連接建立之后執(zhí)行send方法發(fā)送數據console.log("websocket-連接成功")let data = {"hi":"發(fā)送數據"};this.websocketsend(JSON.stringify(data));},websocketonerror(){//連接建立失敗重連this.initWebSocket();},websocketonmessage(e){ //數據接收const redata = JSON.parse(e.data);console.log("ws--數據接收")this.listData = redata.data.records;console.log(redata)},websocketsend(Data){//數據發(fā)送this.websock.send(Data);},websocketclose(e){ //關閉console.log('斷開連接',e);},


在有數據操作的地方只需向服務端發(fā)送消息即可 new OneWebSocket().onMessage(msg);

于是實現了自己想要的功能,以此記錄

《新程序員》:云原生和全面數字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的页面实时数据监听的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。