項目中有個功能需要使用webScoket,需求很簡單,就是當后台一段業務邏輯執行后,通過webScoket發送一個消息到前端;看了下項目依賴,
然后再網上搜了一下,說是jetty啟動類里面要加一句這個:
然后websocket后端代碼是這樣的

1 package com.gmyl.parking.websocket; 2 3 import java.io.IOException; 4 import java.util.Set; 5 import java.util.concurrent.CopyOnWriteArraySet; 6 7 import javax.websocket.OnClose; 8 import javax.websocket.OnMessage; 9 import javax.websocket.OnOpen; 10 import javax.websocket.Session; 11 import javax.websocket.server.ServerEndpoint; 12 13 import org.slf4j.Logger; 14 import org.slf4j.LoggerFactory; 15 16 /** 17 * websocket的service 18 * @author cjz 19 * 20 */ 21 @ServerEndpoint("/webSocket") 22 public class WebSocketDemo { 23 24 private Session session; 25 26 private static Logger logger = LoggerFactory.getLogger(WebSocketDemo.class); 27 28 private static final Set<WebSocketDemo> webSocketSet = new CopyOnWriteArraySet<WebSocketDemo>(); 29 30 31 @OnOpen 32 public void onOpen(Session session) { 33 this.session = session; 34 webSocketSet.add(this); 35 logger.info("【websocket消息】有新的連接, 總數:{}", webSocketSet.size()); 36 } 37 38 @OnClose 39 public void onClose() { 40 webSocketSet.remove(this); 41 logger.info("【websocket消息】連接斷開, 總數:{}", webSocketSet.size()); 42 } 43 44 @OnMessage 45 public void onMessage(String message) { 46 logger.info("【websocket消息】收到客戶端發來的消息:{}", message); 47 } 48 49 50 /** 51 * 推送消息到客戶端 52 * @param message 53 * @throws IOException 54 */ 55 public static void sendMessage(String message) { 56 System.out.println("--------------------:"+webSocketSet.size()); 57 for (WebSocketDemo webSocket: webSocketSet) { 58 logger.info("【websocket消息】廣播消息, message:{}", message); 59 try { 60 webSocket.session.getBasicRemote().sendText(message); 61 //發生異常 關閉連接 62 } catch (Exception e) { 63 logger.info("【websocket消息】廣播消息發送發生異常, exception:{}", e.getMessage()); 64 webSocketSet.remove(webSocket); 65 try { 66 webSocket.session.close(); 67 //連接關閉異常 68 } catch (IOException e1) { 69 logger.info("【websocket消息】關閉連接發生異常, exception:{}", e.getMessage()); 70 } 71 } 72 } 73 } 74 75 }
前端js代碼是這樣的

1 var ws = commonutil.getWebSocket('webSocket'); 2 3 ws.onopen = function (event) { 4 console.log('建立連接'); 5 } 6 7 ws.onclose = function (event) { 8 console.log('連接關閉'); 9 } 10 11 ws.onmessage = function (event) { 12 console.log('收到后台推送的消息:' + event.data) 13 } 14 15 ws.onerror = function () { 16 alert('websocket通信發生錯誤!'); 17 }
業務邏輯的service最后調用了一下:WebSocketDemo.sendMessage("后台消息");
啟動jetty運行項目,打開頁面,頁面控制台打印出:【websocket消息】有新的連接, 總數:1,一切正常,但是調試中發現,觸發WebSocketDemo.sendMessage這個方法的時候,sendMessage這個方法中,第一行代碼:System.out.println("--------------------:"+webSocketSet.size()); 打印出來始終是0;搞了半天,很郁悶,這里明明已經打印出連接數1了,而且webSocketSet是static final的,
private static final Set<WebSocketDemo> webSocketSet = new CopyOnWriteArraySet<WebSocketDemo>(); @OnOpen public void onOpen(Session session) { this.session = session; webSocketSet.add(this); logger.info("【websocket消息】有新的連接, 總數:{}", webSocketSet.size()); }
怎么會變成0呢,然后問了下同事,說是換成tomcat啟動就可以了 ,jetty貌似有什么bug,用不了,然后我把項目放到tomcat中啟動,居然真的可以了。。。。。。。。。。。。。。。。具體的原因還不知道,在此記錄一下,順帶說下jetty的版本是:9.2.9.v20150224,spring版本是3.2.5的,spring4之后的版本,支持websocket, 估計如果用spring4自帶的websocket應該會靠譜些吧。補充下js中的commonutil的代碼:
var commonutil = commonutil || {}; /** * Description: 建立websocket鏈接並返回實例,如果當前瀏覽器不支持websocket則返回null * @returns */ commonutil.getWebSocket = function(subUrl) { var url = 'ws://' + location.host + "/"+ subUrl; if ('WebSocket' in window) ws = new WebSocket(url); else if ('MozWebSocket' in window) ws = new MozWebSocket(url); else alert('當前瀏覽器不支持websocket,請使用IE10+、Chrome17+、Firefox7+'); return ws; };