由於項目需要,前端向後台發起請求後,後台需要分成多個步驟進行相關操作,而且不能確定各步驟完成所需要的時間
倘若使用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:第一篇隨筆です,新人初來乍到,難免會有很多缺漏或者錯誤的地方,還請前輩們多多指點)