【反ajax】webSocket实现实时推送功能

来源:互联网 发布:裴蕾网络黄金最新动态 编辑:程序博客网 时间:2024/05/20 23:58

前天就说有时间要研究下webSocket这种实时推技术。已经用Comet实现了一个结合redis发布/订阅功能的小功能,其实还是有点复杂度的。今天有时间,遂了解了下webSocket,发现也没有想象中那么难!

但我研究webSocket做东西还是饶了一大圈,有一种用spring+webSocket做的,略复杂(可能容错性和健壮性更高?),最后卡在404连接上了,用的jar包是spring-websocket-4.2.x.jar及相关依赖jar包。鉴于参考网上的例子并没实现,故作罢。

后来,用了JavaEE7 (jdk1.7+支持)和html5支持的webSocket,问题就显得简单多了。涉及jar包:websocket-api-1.x.jar

 

客户端:

Html代码  收藏代码
  1. <head>  
  2. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  3. <title>发布订阅测试</title>  
  4.       
  5.     <script type="text/javascript">  
  6.         var socket = null;  
  7.         $(function() {  
  8.             var websocket;  
  9. //考虑各种浏览器兼容问题  
  10.             if ('WebSocket' in window) {  
  11.                 websocket = new WebSocket("ws://localhost:8080/amp/socket/webSocketServer");  
  12.             } else if ('MozWebSocket' in window) {  
  13.                 websocket = new MozWebSocket("ws://localhost:8080/amp/socket/webSocketServer");  
  14.             } else {  
  15.                 websocket = new SockJS("http://localhost:8080/amp/sockjs/webSocketServer");  
  16.             }  
  17. //和服务端连接成功后的操作 send操作必须要有  服务端才会可能响应            
  18.             websocket.onopen = function (evnt) {  
  19.                 var data = {appId:'hx', status:'s'};  
  20.                 websocket.send(JSON.stringify(data));//尝试给服务端发送json参数,这也是项目中常见的的  
  21.                 $("#showMsg").append("连接成功!<br/>");  
  22.             };  
  23. //接收到服务端返回的数据后回调  
  24.             websocket.onmessage = function (evnt) {  
  25.                 $("#showMsg").append("(<font color='red'>"+evnt.data+"</font>)<br/>");  
  26.             };  
  27. //连接失败回调  
  28.             websocket.onerror = function (evnt) {  
  29.             };  
  30. //服务端关闭引发  
  31.             websocket.onclose = function (evnt) {  
  32.                 $("#showMsg").append("连接关闭!<br/>");  
  33.             }  
  34.         });  
  35.     </script>  
  36. </head>  
  37. <body>  
  38.     <div id="showMsg" style="border: 1px solid; width: 500px; height: 400px; overflow: auto;"></div>  
  39. </body>  

 服务端:

Java代码  收藏代码
  1. import javax.websocket.OnClose;  
  2. import javax.websocket.OnMessage;  
  3. import javax.websocket.OnOpen;  
  4. import javax.websocket.Session;  
  5. import javax.websocket.server.ServerEndpoint;  
  6.   
  7. import net.sf.json.JSONObject;  
  8.   
  9. @ServerEndpoint("/socket/webSocketServer")  
  10. public class ScrollInfoHandler {  
  11. //接收到客户端的请求  
  12.     @OnMessage  
  13.       public void onMessage(String message, Session session)  
  14.         throws IOException, InterruptedException {  
  15.          
  16.         System.out.println("Received: " + message);  
  17.           
  18.         Map<String, String> params = JSONObject.fromObject(message);  
  19.           
  20.         // Send the first message to the client  
  21.         session.getBasicRemote().sendText("return params after handled: "   
  22.                 + params.get("appId").toUpperCase() + ", " + params.get("status").toUpperCase());  
  23.          
  24.         // Send 3 messages to the client every 5 seconds  
  25.         int sentMessages = 0;  
  26. //模拟推送数据  
  27.         while(true){  
  28.           Thread.sleep(2000);  
  29.           session.getBasicRemote().  
  30.             sendText("This is an intermediate server message. Count: "  
  31.               + Math.random());  
  32.         }  
  33.          
  34.       }  
  35. //和客户端连接成功后      
  36.       @OnOpen  
  37.       public void onOpen() {  
  38.         System.out.println("Client connected");  
  39.       }  
  40. //客户端关闭后       
  41.       @OnClose  
  42.       public void onClose() {  
  43.         System.out.println("Connection closed");  
  44.       }  
  45.       
  46. }  

 如果想和redis发布订阅结合起来,很简单:在服务端的onOpen函数里启动订阅渠道的线程,以及定时检查队列大小的线程,而在onMessage函数里执行定时从队列pop数据并send,在onClose里面写停止线程和情空队列的逻辑 即可啦。

 

下面就来测一测效果!

启动项目,打开这个客户端页面,先观察控制台打印:

Client connected

Received: {"appId":"hx","status":"s"}

说明,服务端已经跟客户端连通,并且收到传递过来的参数了。

观察客户端页面,你会发现:(某一时刻)



 客户端是不断刷新着的,而且也收到了服务端处理参数后传过来的数据了。

若关闭客户端,服务端控制台会打印:Connection closed

若关闭服务端,客户端会这样:



 说明,达到了响应服务端关闭后的效果。

 

以上,只是一个很简单的推送实例。要具体应用到实际项目中是需要不断完善代码以提高其健壮性的。但至少对我而言,服务端主动推送技术终于不再那么神秘和困惑了,以后对实时性要求比较高的地方可以采纳,终于突破ajax的方式了。



转自:http://raising.iteye.com/blog/2272559

0 0
原创粉丝点击