对于一些对数据实时性要求较高的系统,比如股票行情、在线聊天、微博,实现数据的实时推送是必须的。通常实现实时推送的方式有:
1、轮询:隔一段时间发送数据(如:webqq)
2、socket:以往普通的网页是不支持socket接收消息的。可以通过flash或者applet来作为socket的客户端
3、长连接:指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做
在线维持。
----------------------------------------------------------------------------------------------
html5通过window.WebSocket(firefox下是window.MozWebSocket)提供了一种非http的双向连接,这个连接是实时的更是永久的,除非被显示colse。
这就表示只要客户端打开一个Socket并且请求建立了连接(just once),服务端就能实时接收并发送消息,不需手动检测和维持状态。
WebSocket提供的方法和属性可以在firebug中输入Window.WebSocket.prototype看到。
接下去的代码列出了基本的使用思路:
var location = "ws://localhost:port/serlet/xxx";
//服务端处理的servlet
var webSocket = new WebSocket(location);
//webSocket.readyState
var readyStates = {
"CONNECTING":"正在连接“,
”OPEN“ : "已建立连接",
"CLOSING":"正在关闭连接",
"CLOSED":"已关闭连接"
}
webSocket.send(data);//发送数据到服务端,目前只支持文本类型。JSON.stringify(data);JSON.parse(data);
webSocket.onMessage = function(event){
var data = event.data;//从服务端过来的数据
}
webSocket.onOpen = function(event){
//开始通信
}
webSocket.onClose = function(event){
//结束通信
}
webSocket.close();二、一个基于jetty(java服务器)的例子
目前Apache还不支持WebSocket,各种语言都有各自的方式可以实现它,这里在Java中实现了。
步骤一:下载一个jetty,解压放在任意盘下。jetty7及以上才支持WebSocket,下载地址:download.eclipse.org/jetty/stable-7/dist/
步骤二:下载eclipse(不推荐用MyEclipse,比较麻烦,需要安装其他的插件),必须支持jetty7,版本是越高越好。
步骤三:在eclipse中安装插件,help---Install new software...----url为:eclipse-jetty.sourceforge.net/update/
步骤四:新建一个Dynamic Web Project
目录结构如下

步骤五:拷入如下代码:
TailorWebSocketServlet.java
package com.test;
import java.io.IOException;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;
public class TailorWebSocketServlet extends WebSocketServlet {
private static final long serialVersionUID = -7289719281366784056L;
public static String newLine = System.getProperty("line.separator");
private final Set<TailorSocket> _members = new CopyOnWriteArraySet<TailorSocket>();
private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
public void init() throws ServletException {
super.init();
executor.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println("Running Server Message Sending");
for(TailorSocket member : _members){
System.out.println("Trying to send to Member!");
if(member.isOpen()){
System.out.println("Sending!");
try {
member.sendMessage("from server : happy and happiness! "+new Date()+newLine);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}, 2, 2, TimeUnit.SECONDS);
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
getServletContext().getNamedDispatcher("default").forward(request,
response);
}
public WebSocket doWebSocketConnect(HttpServletRequest request,
String protocol) {
return new TailorSocket();
}
class TailorSocket implements WebSocket.OnTextMessage {
private Connection _connection;
public void onClose(int closeCode, String message) {
_members.remove(this);
}
public void sendMessage(String data) throws IOException {
_connection.sendMessage(data);
}
public void onMessage(String data) {
System.out.println("Received: "+data);
}
public boolean isOpen() {
return _connection.isOpen();
}
public void onOpen(Connection connection) {
_members.add(this);
_connection = connection;
try {
connection.sendMessage("onOpen:Server received Web Socket upgrade and added it to Receiver List.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}test.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset = "utf-8"/>
<title>Chat by Web Sockets</title>
<script type='text/javascript'>
if (!window.WebSocket)
alert("window.WebSocket unsuport!");
function $() {
return document.getElementById(arguments[0]);
}
function $F() {
return document.getElementById(arguments[0]).value;
}
function getKeyCode(ev) {
if (window.event)
return window.event.keyCode;
return ev.keyCode;
}
var server = {
connect : function() {
var location ="ws://localhost:8888/servlet/a";
this._ws =new WebSocket(location);
this._ws.onopen =this._onopen;
this._ws.onmessage =this._onmessage;
this._ws.onclose =this._onclose;
},
_onopen : function() {
server._send('send to server : websockets are open for communications!');
},
_send : function(message) {
if (this._ws)
this._ws.send(message);
},
send : function(text) {
if (text !=null&& text.length >0)
server._send(text);
},
_onmessage : function(m) {
if (m.data) {
var messageBox = $('messageBox');
var spanText = document.createElement('span');
spanText.className ='text';
spanText.innerHTML = m.data;
var lineBreak = document.createElement('br');
messageBox.appendChild(spanText);

