天天看點

c 伺服器向web推送消息,伺服器推送初嘗試WebSocket

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