WebSocket

来源:互联网 发布:mac文件导入移动硬盘 编辑:程序博客网 时间:2024/04/28 22:23

一、 认识HTML5WebSocket

HTML5规范中,我最喜欢的Web技术就是正迅速变得流行的WebSocket APIWebSocket提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术。这个新的API提供了一个方法,从客户端使用简单的语法有效地推动消息到服务器。让我们看一看HTML5WebSocket API:它可用于客户端、服务器端。而且有一个优秀的第三方API,名为Socket.IO

二、什么是WebSocket API?

WebSocket API
是下一代客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用wswss协议,可用于任意的客户端和服务器程序。WebSocket目前由W3C进行标准化。WebSocket已经受到Firefox 4Chrome 4Opera 10.70以及Safari 5等浏览器的支持。

WebSocket API
最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。

Ajax
技术很聪明的一点是没有设计要使用的方式。WebSocket为指定目标创建,用于双向推送消息。

三、WebSocket API的用法

只专注于客户端的API,因为每个服务器端语言有自己的API。下面的代码片段是打开一个连接,为连接创建事件监听器,断开连接,消息时间,发送消息返回到服务器,关闭连接。

[Copy to clipboard] [ - ]

CODE:

[javascript] view plain copy
  1. // 创建一个Socket实例  
  2. var socket = new WebSocket('ws://localhost:8080');   
  3.   
  4. // 打开Socket   
  5. socket.onopen = function(event) {   
  6.   
  7.   // 发送一个初始化消息  
  8.   socket.send('I am the client and I\'m listening!');   
  9.   
  10.   // 监听消息  
  11.   socket.onmessage = function(event) {   
  12.     console.log('Client received a message',event);   
  13.   };   
  14.   
  15.   // 监听Socket的关闭  
  16.   socket.onclose = function(event) {   
  17.     console.log('Client notified socket has closed',event);   
  18.   };   
  19.   
  20.   // 关闭Socket....   
  21.   //socket.close()   
  22. };  



让我们来看看上面的初始化片段。参数为URLws表示WebSocket协议。onopenoncloseonmessage方法把事件连接到Socket实例上。每个方法都提供了一个事件,以表示Socket的状态。

onmessage
事件提供了一个data属性,它可以包含消息的Body部分。消息的Body部分必须是一个字符串,可以进行序列化/反序列化操作,以便传递更多的数据。

WebSocket
的语法非常简单,使用WebSockets是难以置信的容易……除非客户端不支持WebSocketIE浏览器目前不支持WebSocket通信。如果你的客户端不支持WebSocket通信,下面有几个后备方案供你使用:

Flash
技术 ——Flash可以提供一个简单的替换。使用Flash最明显的缺点是并非所有客户端都安装了Flash,而且某些客户端,如iPhone/iPad,不支持Flash

AJAX Long-Polling
技术 —— AJAXlong-polling来模拟WebSocket在业界已经有一段时间了。它是一个可行的技术,但它不能优化发送的信息。也就是说,它是一个解决方案,但不是最佳的技术方案。

由于目前的IE等浏览器不支持WebSocket,要提供WebSocket的事件处理、返回传输、在服务器端使用一个统一的API,那么该怎么办呢?幸运的是,GuillermoRauch创建了一个Socket.IO技术。

 

四、环境要求

浏览器

实现了websocket的浏览器:

Chrome

Supported in version 4+

Firefox

Supported in version 4+

Internet Explorer

Supported in version 10+

Opera

Supported in version 10+

Safari

Supported in version 5+

服务器

在服务器端,也出现了一些实现websocket协议的项目:

jetty 7.0.1包含了一个初步的实现

resin 包含有websocket 实现

pywebsocket, apache http server 扩展

apache tomcat 7.0.27 版本

Nginx 1.3.13 版本

jWebSocket java实现版

websocket api在浏览器端的广泛实现似乎只是一个时间问题了,值得注意的是服务器端没有标准的api, 各个实现都有自己的一套api,并且jcp也没有类似的提案,所以使用websocket开发服务器端有一定的风险.可能会被锁定在某个平台上或者将来被迫升级.

 

 

 

样例

一、前端页面

 

[html] view plain copy
  1. <%@ page language="java"import="java.util.*" pageEncoding="UTF-8"%>  
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  3. <html>  
  4.   <head>  
  5.     <title>My JSP'index.jsp' starting page</title>  
  6.     <style type="text/css">  
  7.     .infos{  
  8.         list-style-type: none;  
  9.     }  
  10.     .infos li{  
  11.         border: 1pxsolid #EEE;  
  12.         margin: 2px;  
  13.         font-size: 12px;  
  14.         line-height: 25px;  
  15.         height: 25px;  
  16.     }  
  17.     
  18.     .red{  
  19.         color: red;  
  20.     }  
  21.     .green{  
  22.         color: green;  
  23.     }  
  24.     .blue{  
  25.         color: blue;  
  26.     }  
  27.     </style>  
  28.     <script type="text/javascript" src="jquery1.9.0.js"></script>  
  29.     <script type="text/javascript">  
  30.     var webSocketnull;  
  31.     var flag = true;//全局标记位,标记浏览器是否支持websocket  
  32.     $(function(){  
  33.         if(!window.WebSocket){  
  34.             $("body").append("<h1>你的浏览器不支持WebSocket</h1>");  
  35.             flag = false;  
  36.             return;  
  37.         }  
  38.          
  39.     });  
  40.      
  41.     functionstartConnect(){  
  42.         if(flag == false){  
  43.             return;  
  44.         }  
  45.         var url = "ws://localhost:8080/websocketDemo/websocket";  
  46.         webSocket = newWebSocket(url);  
  47.          
  48.         webSocket.onerror = function(event) {  
  49.             onError(event)  
  50.         };  
  51.         webSocket.onopen = function(event) {  
  52.             onOpen(event)  
  53.         };  
  54.         webSocket.onmessage = function(event) {  
  55.             onMessage(event)  
  56.         };  
  57.          
  58.         //webSocket.send("客户端给服务端发送消息:hello,start");  
  59.          
  60.     }  
  61.     functiononMessage(event) {  
  62.         $(".infos").append("<liclassliclass='blue'>" + event.data + "</li>");  
  63.     }  
  64.     functiononOpen(event) {  
  65.         $(".infos").append("<liclassliclass='green'>已连接至服务器</li>");  
  66.         $("#startBtn").prop("disabled" , true);  
  67.         $("#sendMessageBtn").prop("disabled" , false);  
  68.     }  
  69.     functiononError(event) {  
  70.         $(".infos").append("<liclassliclass='red'>连接服务器发生错误</li>");  
  71.     }  
  72.     function sendMessage(){  
  73.         var msg = "[" + $("#username").val() + "]:" + $("#message_input_id").val();//获取发送信息  
  74.         webSocket.send(msg);//向服务器发送消息  
  75.         //不需要将此信息追加到列表,由后台统一将消息发送给所有  
  76.         //$(".infos").append("<liclassliclass='green'>" + msg + "</li>");//将消息添加至本地列表  
  77.         $("#message_input_id").val("");//清空消息  
  78.     }  
  79.     </script>  
  80.   </head>  
  81.    
  82.   <body>  
  83.      
  84.     <ul class="infos">  
  85.         <li class="red">提示:点击开始连接将连接到服务器</li>  
  86.     </ul>  
  87.     <br/><br/>  
  88.     <input type="button" value="开始连接" id="startBtn"onclick="startConnect()"/><br/><br/>  
  89.     输入名称:<input id="username" value="<%=(int)(Math.random() *1000) %>" style="width: 50px;margin-right:5px;" />  
  90.     <input id="message_input_id" />  
  91.     <input type="button" value="发送消息" id="sendMessageBtn"disabled="disabled" onclick="sendMessage()" />  
  92.      
  93.   </body>  
  94. </html>  
[java] view plain copy
  1. package com.websocket;  
  2.    
  3. import java.io.IOException;  
  4. import java.util.Queue;  
  5. import java.util.Set;  
  6. import java.util.concurrent.ConcurrentLinkedQueue;  
  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. @ServerEndpoint("/websocket")  
  13. public class WebSocketTest {  
  14.     /** 
  15.      * 存储当前有效的session对象 
  16.      */  
  17.     private staticQueue<Session> sessionSet = new ConcurrentLinkedQueue<Session>();  
  18.      
  19.     @OnMessage  
  20.     public voidonMessage(String message, Session currentSession) {  
  21.        System.out.println("Server say:Received:" + message);  
  22.         try {  
  23.             finalSet<Session> sessions = currentSession.getOpenSessions();//获得又少条连接信息  
  24.            System.out.println("检测到连接服务器是对象数量是"+ sessions.size());  
  25.             //客户端互相发送消息  
  26.             for (Sessionsession : sessions) {  
  27.                 session.getBasicRemote().sendText(message);  
  28.             }  
  29.             //  
  30.              sendmessage();  
  31.              sendmessage();  
  32.             /************启动定时公告**************/  
  33.           //  SystemTimer.getInstance();  
  34. //            Test.Test();  
  35.             /**************************/  
  36.         } catch(IOException e) {  
  37.            e.printStackTrace();  
  38.         }  
  39.     }  
  40.     private voidsendmessage() {  
  41.           for (Session session :sessionSet) {  
  42.                     try {  
  43.                            session.getBasicRemote().sendText("李斌:[大家辛苦了,现在时间是[""asdasdasd" + "],我是李斌]");  
  44.                     } catch(IOException e) {  
  45.                            e.printStackTrace();  
  46.                     }  
  47.              }  
  48.               
  49.       }  
  50.       @OnOpen  
  51.     public voidonOpen(Session currentSession) {  
  52.        if(sessionSet.contains(currentSession) == false){  
  53.            sessionSet.add(currentSession);  
  54.            System.out.println("WebSocketTest.onOpen()================Add="+ sessionSet.size());  
  55.         }  
  56.        System.out.println("Server say:Clientconnected");  
  57.     }  
  58.     @OnClose  
  59.     public voidonClose(Session currentSession) {  
  60.         if(sessionSet.contains(currentSession)){  
  61.            sessionSet.remove(currentSession);  
  62.         }  
  63.        System.out.println("Server say:Connectionclosed============Close=" + sessionSet.size());  
  64.     }  
  65.     public staticQueue<Session> getSessionSet() {  
  66.         return sessionSet;  
  67.     }  
  68.      
  69. }  



 

二、后台服务(针对tomcat7.0.55以上版本),


0 0
原创粉丝点击