解決方案一:websocketjavascript
解決方案二:ssehtml
原理:瀏覽器向服務器發送請求後,服務器抓住請求不放,等到數據更新時,服務器再把數據發送給瀏覽器,瀏覽器拿到響應後,再向服務器發送請求,如此循環java
好處:只使用了一次請求,大大減少了服務器的請求數量,減輕服務器壓力,只會在接收到數據更新後才返回響應。web
栗子:ajax
服務端 springboot接收請求spring
@RestController
@Slf4j
public class PushController {
private int count;
/** * 超時時間設置到最大,避免由於超時致使鏈接斷開 */
private SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
@GetMapping(value = "/push")
public SseEmitter push() throws InterruptedException {
return emitter;
}
@GetMapping("/send")
public String send() {
try {
emitter.send("push " + count++);
return "success";
} catch (IOException e) {
e.printStackTrace();
}
return "failed";
}
}
複製代碼
客戶端 js監聽消息瀏覽器
<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>服務器推送示例</title>
</head>
<body>
<div id="msg"></div>
</body>
<script> var source = new EventSource("/springboot/push"); source.onmessage = function (e) { console.info("收到信息"); document.getElementById("msg").innerHTML += `<p>${e.data}</p>`; }; source.onopen = function (e) { console.info("鏈接打開"); console.info(e); }; source.onerror = function (e) { console.info("鏈接錯誤"); console.info(e); }; </script>
</html>
複製代碼
每次訪問send,服務器就會向瀏覽器返回數據springboot
能夠看到一個push請求接收了來自服務器的多個數據服務器