張文康+王治豪+唐建國
摘要:該文論述websocket信息推送技術(shù)的概念,以及如何在高校教學(xué)網(wǎng)絡(luò)系統(tǒng)中設(shè)計實現(xiàn)websocket信息推送。
關(guān)鍵詞:推送技術(shù);高校教學(xué)網(wǎng)絡(luò)系統(tǒng);實時通信
中圖分類號:TP393 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2016)27-0064-02
1 背景
傳統(tǒng)的HTTP request模式存在明顯的缺點,瀏覽器通過不斷向服務(wù)器“輪詢”獲取最新信息,從而占用大量帶寬資源。WebSocket協(xié)議作為HTML5的一種新協(xié)議,很好地解決了這個問題:瀏覽器發(fā)出websocket連接請求,服務(wù)器發(fā)生回應(yīng),產(chǎn)生“握手”,從而使瀏覽器與服務(wù)器之間產(chǎn)生長連接。這個長連接的生命周期是從建立握手到瀏覽器或者服務(wù)器一方主動斷開連接為止,相對于以往的http連接,生命周期長。
2 服務(wù)器信息推送
首先,用戶頁面的布局用的是html的iframe子框架組合,頭部子框架留出一塊位置用戶顯示系統(tǒng)推送消息,同時負(fù)責(zé)與Server端進(jìn)行websocket連接。然后管理員賬號有系統(tǒng)消息選項,進(jìn)入消息面板進(jìn)行消息推送。
關(guān)鍵功能代碼介紹如下。
子frame觸發(fā)同源兄弟frame發(fā)送函數(shù):
function postToServer(){
parent.frames["topFrame"].postToServer();
}
兄弟frame將消息發(fā)送給服務(wù)器:
function postToServer(){
var msg = parent.frames["main"].document.getElementById("pushtext").value;
we.send(msg);
}
Server端存儲在線用戶session的數(shù)據(jù)結(jié)構(gòu)為動態(tài)數(shù)組:
private static ArrayList
若用戶成功用websocket與Server握手時,將該用戶節(jié)點加入數(shù)組:
public void onOpen(WsOutbound outbound){
System.out.println("Open Client");
this.myoutbound = outbound;
mmiList.add(this);}
用戶關(guān)閉網(wǎng)站,與服務(wù)器斷開握手時,刪除該用戶節(jié)點:
public void onClose(int status){
System.out.println("Close Client.");
mmiList.remove(this);
}
系統(tǒng)消息推送時,Server端將從管理員用戶接收來的消息發(fā)送給所有在線用戶;發(fā)送時通過遍歷在線用戶session數(shù)組進(jìn)行發(fā)送:
public void onTextMessage(CharBuffer cb) throws IOException{
System.out.println("Accept Message:"+cb);
for(MyMessageInbound mmib : mmiList){
CharBuffer buffer = CharBuffer.wrap(cb);
mmib.myoutbound.writeTextMessage(buffer);
mmib.myoutbound.flush();
}
}
3 客戶端信息推送
websocket技術(shù)如果是管理員面向全體在線用戶就是系統(tǒng)推送,而如果是用戶與用戶間互相進(jìn)行推送就升級為了在線聊天。
關(guān)鍵功能代碼介紹如下。
//發(fā)送消息給Server
function sendMsg() {
var fromName = parent.frames["main"].document.getElementById("userName").innerHTML;
var toName = parent.frames["main"].document.getElementById(name).value; //發(fā)給誰
var content = parent.frames["main"].document.getElementById(writeMsg).value; //發(fā)送內(nèi)容
ws.send(fromName+","+toName+","+content);
}
//從Server接收消息
ws.onmessage = function(e){
if(flage == 0){ parent.frames["BoardMenu"].document.getElementById("message").inn erHTML += e.data + "
";
}else{ parent.frames["main"].document.getElementById("xiaoxi").textContent += e.data + "\n";
} }
//Server端存儲用戶數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)是哈希表
public static HashMap
HashMap
String msgString = msg.toString();
String m[] = msgString.split(",");
map.put("fromName", m[0]);
map.put("toName", m[1]);
map.put("content", m[2]);
return map;
}
//服務(wù)器發(fā)送給消息接收者
protected void onTextMessage(CharBuffer msg) throws IOException {
//用戶所發(fā)消息處理后的map
HashMap
//上線用戶集合類map
HashMap
String fromName = messageMap.get("fromName"); //消息來自人 的userId
String toName = messageMap.get("toName"); //消息發(fā)往人的 userId
//獲取該用戶
MessageInbound messageInbound = userMsgMap.get(toName);
MessageInbound messageInbound2 = userMsgMap.get(fromName); //在倉庫中取出發(fā)往人的MessageInbound
if(messageInbound!=null){ //如果發(fā)往人 存在進(jìn)行操作
WsOutbound outbound = messageInbound.getWsOutbound();
String content = messageMap.get("content"); //獲取消息內(nèi)容
String msgContentString = fromName + " " + content; //構(gòu)造發(fā)送的消息
//發(fā)出去內(nèi)容
CharBuffer toMsg = CharBuffer.wrap(msgContentString.toCharArray());
outbound.writeTextMessage(toMsg); //
outbound.flush();
if(messageInbound2!=null){ //如果發(fā)往人 存在進(jìn)行操作
WsOutbound outbound2 = messageInbound2.getWsOutbound();
String content2 = messageMap.get("content"); //獲取消息內(nèi)容
String msgContentString2 = fromName + " " + content2; //構(gòu)造發(fā)送的消息
//發(fā)出去內(nèi)容
CharBuffer toMsg2 = CharBuffer.wrap(msgContentString2.toCharArray());
outbound2.writeTextMessage(toMsg2);
outbound2.flush();
}
}else{
WsOutbound outbound3 = messageInbound2.getWsOutbound();
String error = "系統(tǒng)消息:對不起,對方不在線!";
CharBuffer toMsg3 = CharBuffer.wrap(error.toCharArray());
outbound3.writeTextMessage(toMsg3);
outbound3.flush();
}
4 結(jié)束語
本文基于websocket技術(shù)實現(xiàn)了網(wǎng)絡(luò)教學(xué)系統(tǒng)的信息推送服務(wù),實現(xiàn)了管理員面向全體在線用戶就是系統(tǒng)推送,用戶與用戶間的在線聊天等功能。
參考文獻(xiàn):
[1] Williams N S. Java Web高級編程[M]. 王肖峰, 譯. 北京: 清華大學(xué)出版社, 2015.
[2] Ja Lengstorf, Leggetter P.構(gòu)建實時Web應(yīng)用[M]. 肖志清, 譯.北京: 機械工業(yè)出版社, 2013.
[3] 趙振,王順. Web異步與實時交互iframe Ajax WebSocket開發(fā)實戰(zhàn)[M]. 北京: 人民郵電出版社, 2016.