项目中有个功能需要使用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; };