伺服器推送,顧名思義,是指伺服器向用戶端推送資料,并且是主動的。在初學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