在這裏先提供兩種思路。要實現頁面數據的實時加載有兩種方式,第一種是長輪詢的方式。要麼是後臺長輪詢,檢測到數據變化時,通知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(請標明添加好友原因)