服务器推送,顾名思义,是指服务器向客户端推送数据,并且是主动的。在初学web项目的过程中,我们一开始都是做客户端或浏览器向服务器发送请求,然后得到服务器响应后取数据做功能。这种一问一答的形式往往很不及时,所有就有了设置定时器向服务器发请求的解决办法。但是这种解决办法更加的耗资源,不管是服务端还是客户端。于是有了comet、ajax轮询、长连接等解决方法,这些方法各有优劣,在此不一一描述。这里写一个目前比较常用的例子,用的是WebSocket技术。使用工具:myEclipse
第一步:在html或者jsp页面穿件一个WebSocket链接
//设定WebSocket,注意协议是ws,请求是指向对应的WebSocketServlet的
var ws = new
WebSocket("ws://localhost:80/webSocket/webServlet");
//WebSocket握手完成,连接成功的回调
//有个疑问,按理说new
WebSocket的时候就会开始连接了,如果在设置onopen以前连接成功,是否还会触发这个回调
ws.onopen = function() {
//请求成功
};
//收到服务器发送的文本消息, event.data表示文本内容
ws.onmessage = function(message) {
document.getElementByIdx_x("talkInfo").innerHTML+=message.data+"
";
};
//关闭WebSocket的回调
ws.onclose = function() {
//alert('Closed!');
};
// 通过WebSocket想向服务器发送一个文本信息
function postToServer() {
ws.send(document.getElementByIdx_x("content").value);
document.getElementByIdx_x("content").value = "";
}
//关闭WebSocket
function closeConnect() {
ws.close();
}
* {
margin: 0 auto;
padding: 0px;
font-size: 12px;
font-family: "微软雅黑";
line-height: 26px;
}
#bigbox {
margin:0px auto;
padding:0px;
width:70%;
}
#talkInfo{
width:100%;
height:500px;
border:1px solid red;
overflow: scorll;
}
#operation{
width:100%;
height:30px;
margin-top:10px;
}
#content{
height:30px;
line-height:30px;
}
第二步:写一个Servlet用来实现链接和一些简单功能
package com.yc.websockets;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import
org.apache.catalina.websocket.MessageInbound;
import
org.apache.catalina.websocket.StreamInbound;
import
org.apache.catalina.websocket.WebSocketServlet;
import
org.apache.catalina.websocket.WsOutbound;
@SuppressWarnings({ "serial", "deprecation", "unused"
})
public class WebSocketTest extends WebSocketServlet
{
private static List userList = new ArrayList();
private HttpSession session;
@Override
protected
StreamInbound createWebSocketInbound(String str, HttpServletRequest
request) {
session=request.getSession();
return new MyMessageInbound();
}
//基于消息的WebSocket实现类(带内消息),应用程序应当扩展这个类并实现其抽象方法onBinaryMessage和onTextMessage。
//要用到MessageInbound中的一些方法自己写一个内部类,继承自MessagInbound,完成收到WebSocket消息后的逻辑处理
private class
MyMessageInbound extends MessageInbound {
//
WsOutbound:提供发送消息到客户端的功能。它提供的所有向客户端的写方法都是同步的,可以防止多线程同时向客户端写入数据。
WsOutbound myoutbound;
public void onOpen(WsOutbound outbound) {
try
{
System.out.println("Open
Client.");
this.myoutbound =
outbound;
userList.add(this);
//添加当前用户
//向客服端发送信息
outbound.writeTextMessage(CharBuffer.wrap("Hello!"));
} catch
(IOException e) {
e.printStackTrace();
}
}
@Override
public void onClose(int status) {
userList.remove(this); //移除当前用户
}
@Override
public void onTextMessage(CharBuffer cb) throws
IOException {
for
(MyMessageInbound mmib:userList){ //循环向所有在线用户发送当前用户的信息
CharBuffer buffer =
CharBuffer.wrap(cb);
mmib.myoutbound.writeTextMessage(buffer);
//调用指定用户的发送方法发送当前用户信息
mmib.myoutbound.flush();
//清空缓存
}
}
@Override
public void onBinaryMessage(ByteBuffer bb)
throws IOException {
}
}
}
第三步:配置xml,用myEclipse的在写Servlet的时候就可以吧web.xml配置好了
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
webServlet
com.yc.websockets.WebSocketTest
webServlet
/webServlet
index.jsp