websocket實現頁面資料實時載入(Springboot+vue)
在這裡先提供兩種思路。要實現頁面資料的實時載入有兩種方式,第一種是長輪詢的方式。要麼是後臺長輪詢,檢測到資料變化時,通知websocket你該更新一下資料了。要麼是前臺長輪詢,每隔一段時間發起請求獲取資料。結合前後臺長輪詢的方式,這裡想給各位推薦第二種--手動通知。我不頻繁發起請求,我只在當我後臺資料發上變化時,我通知websocket你該更新一下資料了。
在這篇文章中,前臺長輪詢的方式是最不建議的。所以不予以介紹。在這裡只介紹後臺長輪詢和手動通知的方式。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>5.0.2.RELEAS</version> </dependency> |
後臺不建議採用多執行緒方式。因為每次,比如5秒就開啟一個執行緒專門來檢視資料庫,判斷有無變化資料,將會大大佔用伺服器資源。可使用心跳服務的方式,每隔一段時間就查詢一次。
import org.springframework.stereotype.Component;
import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet;
/** * socket連線 */ @Component @ServerEndpoint(value = "/Jqcase") public class JqWebSocket {
private Session session = null; private Integer linkCount=0;
private static CopyOnWriteArraySet<JqWebSocket> webSocketSet=new CopyOnWriteArraySet<JqWebSocket>(); /** * 新的客戶端連線呼叫的方法 * @param session */ @OnOpen public void onOpen(Session session) throws IOException { System.out.println("-------------有新的客戶端連線----------"); linkCount++; this.session = session; webSocketSet.add(this); }
/** * 收到客戶端訊息後呼叫的方法 * @param message */ @OnMessage public void onMessage(String message){ System.out.println("發生變化"+message); try{ sendMessage("發生變化"+message); }catch (Exception e){ e.printStackTrace(); } }
/** * 傳送資訊呼叫的方法 * @param message * @throws IOException */ public static void sendMessage(String message) throws IOException { for (JqWebSocket item : webSocketSet) { item.session.getBasicRemote().sendText(message); } }
@OnClose public void onClose(){ //thread1.stopMe(); linkCount--; webSocketSet.remove(this); }
@OnError public void onError(Session session,Throwable error){ System.out.println("發生錯誤"); error.printStackTrace(); } } |
這裡實現的思路是,當查詢回來的資料,第一條資料的編號發生改變,就通知websocket發生改變。在上面的websocket可能會有空指標異常,所以需要獲取上下文。配置上下文方法見下:
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware;
public class FrameSpringBeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; }
@SuppressWarnings("unchecked") public static <T> T getBean(String name){ return (T) applicationContext.getBean(name); }
public static <T> T getBean(Class<T> cls){ return applicationContext.getBean(cls); }
} |
注意:要對應後臺的@ServerEndpoint(value = "/hesocket")
onmessage是websocket接收到資訊執行的操作,在那裡操作重新獲取資料載入即可。
initHESocket(){ const wsuri = "ws://68.34.21.148:9998/hczz/hesocket"; this.websock= new WebSocket(wsuri); //console.log("我連線事件處置websocket了"); this.websock.onmessage = this.heonmessage; this.websock.onopen = this.heonopen; this.websock.send = this.hesend; this.websock.onclose = this.heclose; //console.log(this.websock);
}, heonopen(){ //連線建立之後執行send方法傳送資料 //let actions = {"test":"12345"}; //this.websocketsend(JSON.stringify(actions)); }, heonmessage(e){ //console.log("在這裡執行處置事件重新整理操作,謝謝!!") // console.log(e) this.getpendingEvents(); this.gethandingEvents(); }, hesend(data){ //資料傳送 this.websock.send(data); }, heclose(){ console.log("斷開websocket"); this.initHESocket(); },
|
寫得比較粗糙,有寫得錯誤的或者有更好方法,歡迎評論、聯絡交流。
程式碼在https://download.csdn.net/download/linbyte/10874327 僅作為學習交流用途,禁止用於任何商業用途。
聯絡QQ:694335719
微信:lin69335719(請標明新增好友原因)