WebSocket實現前臺實時顯示資料庫資料
阿新 • • 發佈:2019-02-10
業務邏輯:
在瀏覽器和伺服器之間建立WebSocket雙工連線,啟動一個執行緒,設定私有變數資料修改時間,迴圈讀取資料庫實時表中某個感測器的資料修改時間,與私有變數進行對比,如果相同則不做任何改動,若不同,則把查詢到的時間賦值給私有變數,同時向瀏覽器傳送推送訊息,前端通過ajax傳送請求更新資料。
新增依賴:
用之前 需查詢依賴版本是否與spring版本相容
WebSocket依賴:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency>
日期比較依賴:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.2</version>
</dependency>
前端功能程式碼及作用:
var websocket = null; //判斷當前瀏覽器是否支援WebSocket if ('WebSocket' in window) { //建立連線,這裡的/websocket ,是Servlet中註解中的那個值 websocket = new WebSocket("ws://localhost:8080/專案名/websocket"); } else { alert('當前瀏覽器不支援WebSocket'); } //連線發生錯誤的回撥方法 websocket.onerror = function () { //發生連線錯誤的處理程式碼 }; //連線成功建立的回撥方法 websocket.onopen = function () { //連線成功的處理程式碼 } //接收到訊息的回撥方法 websocket.onmessage = function (event) { console.log(event.data); if(event.data=="1"){ //接收到訊息的處理程式碼 } } //連線關閉的回撥方法 websocket.onclose = function () { //連線關閉時的處理程式碼 } //監聽視窗關閉事件,當視窗關閉時,主動去關閉WebSocket連線,防止連線還沒斷開就關閉視窗,server端會拋異常。 window.onbeforeunload = function () { closeWebSocket(); } //關閉WebSocket連線 function closeWebSocket() { websocket.close(); }
後端功能程式碼及作用:
//在相對路徑中釋出端點websocket,註解中的路徑要與前端程式碼對應“ websocket = new WebSocket("ws://localhost:8080/專案名/websocket");” @ServerEndpoint("/websocket") public class WebSocketServlet { MyThread thread1=new MyThread(); Thread thread=new Thread(thread1); //用來存放每個客戶端對應的MyWebSocket物件。 private static CopyOnWriteArraySet<WebSocketServlet> webSocketSet = new CopyOnWriteArraySet<WebSocketServlet>(); private javax.websocket.Session session=null; //開啟連線 @OnOpen public void onOpen(Session session) throws IOException{ this.session=session; webSocketSet.add(this); System.out.println(webSocketSet); //開啟一個執行緒對資料庫中的資料進行輪詢 thread.start(); } //關閉連線 @OnClose public void onClose(){ thread1.stopMe(); webSocketSet.remove(this); } //給伺服器傳送訊息告知資料庫發生變化 @OnMessage public void onMessage(int count) { System.out.println("發生變化"+count); try { sendMessage(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //出錯的操作 @OnError public void onError(Throwable error){ System.out.println(error); error.printStackTrace(); } /** * 這個方法與上面幾個方法不一樣。沒有用註解,是根據自己需要新增的方法。 * @throws IOException * 傳送自定義訊號,“1”表示告訴前臺,資料庫發生改變了,需要重新整理 */ public void sendMessage() throws IOException{ //群發訊息 for(WebSocketServlet item: webSocketSet){ item.session.getBasicRemote().sendText("1"); } } }
定義執行緒:
public class MyThread implements Runnable{
private Date sum;
private Date new_sum;
private boolean stopMe = true;
public void stopMe() {
stopMe = false;
}
public void run() {
//查詢資料更新時間
UrlDao urlDao=new UrlDao();
new_sum=urlDao.selectTime();
WebSocketServlet wbs=new WebSocketServlet();
while(stopMe){
new_sum=urlDao.selectCount();
if(sameDate(sum, new_sum )){
System.out.println("change");
sum=new_sum;
wbs.onMessage(sum);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static Boolean sameDate(Date dt1 , Date dt2 ){
LocalDate ld1 = new LocalDate(new DateTime(dt1));
LocalDate ld2 = new LocalDate(new DateTime(dt2));
return ld1.equals( ld2 );
}
}