java 板


LINE

Blog 版:http://pt2club.blogspot.com/2011/09/channel-api.html 我不是故意要提 JavaScript 的 只是這玩意一定得搭配 JavaScript 啊...... Orz ======== Google App Engine 自 1.4.0 版推出 Channel API, 使 server 與 browser 之間可以不透過 pooling 的方式做到 server push。 不過 Google 官方教學文件摻雜了井字遊戲的元素, 反而無法專注於 Channel API 上。 這篇文章打算用最原始的聊天室,透過實做的過程來體驗一下 Java 版 Channel API。 因為是簡易聊天室,所以只打算提供一個共用的聊天室, 然後用兩個 JSP 檔來解決:room.jsp、server.jsp。 room.jsp 負責處理使用者輸入訊息、顯示對話;server.jsp (應該寫成 servlet 比較好,因為是簡易聊天室......) 負責接收訊息、並廣播出去。 對應到 Channel API 的用詞,一個聊天室就是一個 channel, 同一個 channel 的成員(client 端)就會接收到其他成員所發出的訊息(message)。 所以,從 server 的角度,需要作這些事情: 1.開啟一個 channel 2.給加入這個 channel 的 client 專屬識別碼(token) 3.接收訊息的管道 4.發送訊息的功能 在 Channel API 當中只要決定 channel 的 名字就算做到第一點了, 因為是簡易聊天室,所以把名稱訂死為「PsMonkey」。 產生 token 的方法是: //Java code ChannelService channel = ChannelServiceFactory.getChannelService(); String token = channel.createChannel("PsMonkey"); 因為是簡易聊天室,所以把 token 透過 JSP 產生、 並塞進 client 端的 JavaScript 碼。 接下來看 client 端的部份。首先建立連線的部份: //JavaScript code var channel = new goog.appengine.Channel("<%=token%>"); //token 傳入 var handler = { 'onopen' : onOpened, //建立連線、channel.open() 就會觸發 'onmessage' : onMessage, //有訊息傳入時 'onerror' : onError, //發生錯誤時 'onclose' : onClosed, //連線結束時 }; socket = channel.open(handler); socket 就是實際處理通訊的部份。 這段的重點是透過 handler 設訂 socket 各種狀況會觸發的 method。 仔細想一下就會發現:「只有接收訊息的 method,那傳送訊息呢?」 Channel API 要解決的問題是 server push, client 端傳送訊息的功能並不包含在其中,得透過 HTTP request 來作到。 所以送訊息的 method 會長的像這樣: //JavaScript code sendMessage = function(message) { var xhr = new XMLHttpRequest(); xhr.open('POST', 'server.jsp?msg='+message, true); xhr.send(); }; 於是用 sendMessage() 來設定在 client 端連線時送出「____ 進入聊天室」、 離線時送出「____ 離開聊天室」: //JavaScript code onOpened = function() { sendMessage("「"+name + "」進入聊天室......"); }; onClosed = function(){ sendMessage("「"+name + "」離開聊天室......"); } 有訊息進來的時候,就把訊息塞進某一個 element 的尾巴。 這邊要注意一點,參數 msg 不是單純的字串,而是一個物件, data 這個 field 才是真正回傳的資料。 //JavaScript code onMessage = function(msg) { document.getElementById("output").innerHTML += msg.data +"<br />""; } 接著來看一下負責處理 client 端 sendMessage() 的 server.jsp,直接貼程式碼: //Java code <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="com.google.appengine.api.channel.*"%> <% String message = request.getParameter("msg"); ChannelService channel = ChannelServiceFactory.getChannelService(); channel.sendMessage( new ChannelMessage("PsMonkey", message) ); %> 在從 request 當中取得 clinet 端傳上來的訊息後, 連同 channel 的名稱包成一個 ChannelMessage, 透過 ChannelService.sendMessage() 傳出去, 就會觸發 client 端的 socket.onMessage 了。 再透過一些簡單的 HTML 與 JavaScript 來讓 client 端 送出訊息時能呼叫到 sendMessage(),聊天室就完成了! 是不是很簡單呢? [扭扭] 最後補充 socket 的幾件事情: onerror 會傳入一個參數,其中有兩個 field: description:錯誤的描述 code:HTTP 錯誤代碼 目前只測出 idle 太久、server 切斷連線時會觸發 socket 還有一個 method:close(),呼叫成功會觸發 socket.onclose。 完整可以跑的範例放在... (我懶得貼網址了 XD) -- 錢鍾書: 說出來的話 http://www.psmonkey.org 比不上不說出來的話 Java 版 cookcomic 版 只影射著說不出來的話 and more...... --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.25.0.25







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Gossiping站內搜尋

TOP