由於項目需要,前端向後台發起請求後,後台需要分成多個步驟進行相關操作,而且不能確定各步驟完成所需要的時間
倘若使用ajax重復訪問後台以獲取實時數據,顯然不合適,無論是對客戶端,還是服務端的資源很是浪費
這種情況下,WebSocket能夠解決此問題
它不像普通的http請求或者ajax訪問,返回相應的結果就關閉了連接
WebSocket在個人淺薄的知識看來是屬於長連接,能保持連接,隨時收發數據
所以對WebSocket進行了初步了解,並按照相關的教程嘗試做了一個簡易demo
首先需要了解的是,WebSocket的幾個基本操作
其中,服務端和客戶端都能監聽三類基本事件:
1、onopen(打開連接) 2、onmessage(發送數據) 3、onclose(關閉連接)
本次的demo中使用了tomcat7.0作為服務端,據悉7.0以上的版本才支持WebSocket
首先使用eclipse創建一個web project
在工程根目錄下的WEB-INF/lib目錄中導入tomcat7.0的lib文件夾中的 tomcat7-websocket.jar 和 websocket-api.jar
然後在src目錄下創建第一個類(重點在於繼承ServerApplicationConfig)
package cn.test.websocket; import java.util.Set; import javax.websocket.Endpoint; import javax.websocket.server.ServerApplicationConfig; import javax.websocket.server.ServerEndpointConfig; public class ApplicationConfig implements ServerApplicationConfig { //掃描注解 @Override public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scan) { System.out.println("scan WebSocket" + scan.size()); //返回(起到過濾的作用,可以在返回前把裡面部分類進行過濾) return scan; } //實現接口 @Override public Set<ServerEndpointConfig> getEndpointConfigs( Set<Class<? extends Endpoint>> arg0) { // TODO Auto-generated method stub return null; } }
接著創建第二個類,這個類用來處理WebSocket傳送過來的數據(重點在於該類有@ServerEndpoint的注解)
package cn.test.websocket; import javax.websocket.OnClose;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; //注解規定了訪問的URL @ServerEndpoint("/echo") public class EchoSocket { /** * 客戶端有連接的時候就會調用這個方法 */ @OnOpen public void open(Session session, EndpointConfig config){ System.out.println(session.getId()+"#############"); } /** * 客戶端連接斷開就會調用此方法 */ @OnClose public void close(Session session,CloseReason reason){ System.out.println(session.getId() + "連接關閉了"); } /** * 接收到客戶端的信息 * @param msg * @param last */ @OnMessage public void message(Session session,boolean last,String msg){ System.out.println("客戶端說" + msg); try { session.getBasicRemote().sendText("ni hao too"); Thread.sleep(3000);//三秒後再發送一條信息,用於驗證是否實現數據實時更新 session.getBasicRemote().sendText("ni hao too twice"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
/** *錯誤監聽(當沒有關閉socket連接就關閉浏覽器會異常) */
@OnError
public void error(Session session, Throwable error){
String id = session.getId();
System.out.println("出錯的session的id是" + id);
}
public EchoSocket(){ System.out.println("Socket對象創建"); //通過對象的創建可以知道不同socket之間的通信不會共享成員變量 } }
本案例中,使用的是基於注解的方法,讓ApplicationConfig掃描注解
(實際上還有實現接口實現的方法,同理可以讓ApplicationConfig掃描實現接口的類)
後台所需的類已經寫好了,接下來就寫一個簡單的jsp頁面
在工程下的index.jsp如下(實際上html也可以)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>WebSocket示例</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="description" content="This is my page"> </head> <body> <button onclick="subOpen();">open</button><br/> <input type="text" name="msg" id="msg"><br/> <button onclick="send();">發送</button> <div id="div"></div> </body> <script type="text/javascript"> var ws; // 就是一個通信管道 var target = "ws://127.0.0.1:8080/WebSocket/echo";//服務端的url,注意以ws開頭 function subOpen(){ //三個判斷用於獲取ws通信管道(浏覽器兼容) if('WebSocket' in window){ ws = new WebSocket(target); }else if('MozWebSocket' in window){ ws = new MozMozWebSocket(target); }else{ alert("WebSocket is not supported by this browse"); return; } //ws.onopen = function(){} 鏈接開啟會執行方法 //ws.onclose = function(){} 斷開連接會執行方法 //以上兩個實際用處並不多,主要是下面的 //服務器又信息返回就執行方法 ws.onmessage=function(event){ //服務端一返回內容,就把該內容放到div標簽當中 document.getElementById("div").innerHTML = event.data; //方便在控制台查看返回內容的具體信息 console.info(event); }; }; function send(){ //點擊發送按鈕就把輸入框裡的內容發送給服務器,並把輸入框的內容清空 var msg = document.getElementById("msg").value; ws.send(msg); document.getElementById("msg").value = ""; }; </script> </html>
至此,demo已經編寫完畢,將工程部署到tomcat7.0,啟動tomcat並訪問localhost:8080/WebSocket可看到以下簡易頁面
點擊open按鈕,發起websocket連接,服務端控制台會輸出
Socket對象創建
0#############
在網頁輸入框輸入“你好”後點擊“發送”按鈕
服務端控制台輸出
客戶端說你好
網頁端先顯示"ni hao too",三秒後,又顯示"ni hao too twice"
(三秒鐘太短了懶得去截第一個效果的圖片的,反正大家都懂的2333)
重復再網頁輸入信息點擊發送後能重復展現同樣的效果
顯然,WebSocket非常靈活好用
(ps:第一篇隨筆です,新人初來乍到,難免會有很多缺漏或者錯誤的地方,還請前輩們多多指點)