前段時間在研究websocket.其中遇到了一些bug。這裏跟你們分享這過程。前端
首先介紹一下websocketjava
WebSocket是HTML5的一種新協議,實現了瀏覽器和服務器的雙全工通訊,能更好的節省服務器資源和帶寬並達到實時通訊。同時WebSocket是創建在TCP之上,同HTTP同樣經過TCP來通訊。WebSocket須要相似TCP的客戶端和服務端的握手鍊接而後進行通訊。但websocket與傳統的HTTP每次請求-應答都須要客戶端和服務端創建鏈接模式不一樣的是websocket相似socket的TCP長鏈接的通信模式,在客戶端斷開websocket鏈接或服務端斷開鏈接前,不須要客戶端和服務端從新發起鏈接請求。一旦websocket創建鏈接以後,後續的數據都是以幀序列的形式傳輸。web
此websocket demo的後臺使用的是Java寫的,以下:api
1 import java.util.concurrent.CopyOnWriteArraySet; 2 3 import javax.websocket.OnClose; 4 import javax.websocket.OnError; 5 import javax.websocket.OnMessage; 6 import javax.websocket.OnOpen; 7 import javax.websocket.Session; 8 import javax.websocket.server.ServerEndpoint; 9 10 11 @ServerEndpoint("/myecho") 12 public class WSDemo { 13 14 // Logger log = Logger.getLogger(getClass()); 15 16 //當前在線人數 17 private static int onlineCount = 0; 18 //用一個set集合保存幾個websocket實例 19 private static CopyOnWriteArraySet<WSDemo> wsSet = new CopyOnWriteArraySet<WSDemo>(); 20 //websocket的session 21 private Session session; 22 23 /** 24 * 客戶端新建websocket時會觸發(握手協議後) 25 * 並加入當前的set集合中 26 * @param session 27 */ 28 @OnOpen 29 public void wsOpen(Session session) { 30 this.session = session; 31 wsSet.add(this);//加入集合 32 // 在線人數加1 33 addOnlineCount(); 34 } 35 36 //當websocket退出的時候觸發,並在set集合中刪除當前websocket 37 @OnClose 38 public void wsClose(){ 39 wsSet.remove(this); //刪除 40 //在線人數-1 41 subOnlineCount(); 42 } 43 44 /** 45 * 接收到客戶端發來的消息並處理,同時也像客戶端發送消息 46 * @param message 47 * @param session 48 */ 49 @OnMessage 50 public void wsMessage(String message, Session session) { 51 sendMessage(message); 52 System.out.println("=====客戶端發來消息:" + message); 53 System.out.println("======websocket 數量:" + wsSet.size()); 54 //羣發消息 55 for(WSDemo wss: wsSet) { 56 wss.sendMessage("服務端發來的消息"); //向客戶端發送消息 57 } 58 } 59 60 //websocket錯誤的時候丟出一個異常 61 @OnError 62 public void wsError(Session session, Throwable throwable) { 63 throw new IllegalArgumentException(throwable); 64 } 65 66 //send message 發送消息處理方法 67 public void sendMessage(String message) { 68 try { 69 this.session.getBasicRemote().sendText(message); 70 System.out.println("===============發送了消息:" + message); 71 } catch (Exception e) { 72 // TODO: handle exception 73 System.out.println(e.getMessage()); 74 } 75 } 76 77 // get onlinecount 78 public static synchronized int getOnlineCount() { 79 return onlineCount; 80 } 81 82 // +1 83 public static synchronized void addOnlineCount() { 84 WSDemo.onlineCount++; 85 System.out.println("++++++++++++++上線人數+1:" + onlineCount); 86 } 87 88 //-1 89 public static synchronized void subOnlineCount() { 90 WSDemo.onlineCount--; 91 System.out.println("---------------線上人數-1:" + onlineCount); 92 } 93 94 }
前端代碼就相對簡單,直接使用咱們註冊的'/myecho' websocket服務端瀏覽器
var wsuri = "ws://localhost:8080/wsdemo/myecho"; var ws = null; function dows() { //判斷瀏覽器是否支持websocket if("WebSocket" in window || window.WebSocket) { ws = new WebSocket(wsuri); } else { alert("browser not support websocket..."); // throw "browser not support websocket..."; //這種寫法是能夠的 throw new Error("browser not support websocket...");//這種也是能夠 return false } ws.onopen = function(evt) { wsObj.wsopen(evt); } ws.onmessage = function(evt) { wsObj.wsmsg(evt); } ws.onclose = function(evt) { wsObj.wsclose(evt); } ws.onerror = function(evt) { wsObj.wserror(evt); } /*ws.send("my message...");*/ } var wsObj = { wsopen:function(evt) { console.log(evt.type); document.querySelector("#clientSuc").innerHTML = "websocket connect success..."; }, wsmsg:function(msg) { debugger; console.log("type:"+msg.type); //document.getElementById("msg").innerHTML = msg.data; console.log("data:" + msg.data); document.querySelector("#msg").innerHTML = msg.data; // ws.close(); //關閉websocket }, wsclose:function(evt) { console.log("type:" + evt.type); }, wserror:function(evt) { console.log("type:" + evt.type); } }; function sendMsg (){ var msg = "hello websocket..."; ws.send(msg); } function closeWebsocket() { ws.close(); } window.addEventListener("load", dows, false);
這裏須要注意到的是:由於websocket是j2ee 7 以上的版本因此須要jdk版本1.7以上,並且tomcat服務器的支持也有區別,好比tomcat7不會自動把'websocket-api.jar'引入,而tomcat8則會。若是使用tomcat7的版本且沒有本身手動添加tomcat的library引入'websocket-api.jar'這個jar包的話前臺會報404找不到websocket服務的異常。這個bug我搞了半天才知道原來是tomcat版本的問題。tomcat