Project darkstar
Project darkstar 或者又稱 sun game server (簡稱sgs) 是sun為大型多用戶在線游戲(mmo) 和虛擬社區應用而開發的一套軟件基礎架構.目的是為了簡化此類應用程序的開發,具體的介紹可見:Project darkstar faq. 這里有一篇中文的詳細介紹
Darkmud
Darkmud 是sun在javaone大會上為了演示sgs 而開發的一個 文字型mud 游戲.在darkmud 的主頁上沒有release 的下載鏈接,需要直接從svn checkout 它的代碼.checkout 出來的代碼包含了服務器端的mud 游戲實現和一個簡單的swing 客戶端.這是swing client 運行時的截圖:
Sgs server 通信模型
Sgs 和客戶端之間的通信是在tcp協議之上通過直接傳輸字節流來完成,例如從client 向server 傳輸數據就是: SimpleClient.send(ByteBuffer buf); 客戶端和服務器端的通信協議是公開的,所以各種語言,只要支持socket 的tcp通信,都可以連接到 sgs 上,官方目前支持java和c的客戶端api,但已經有一些第三方開發的客戶端api出現,例如在flash/as3 平臺就可以使用這個. 客戶端和服務器端接收對方的數據都是事件驅動的,發送數據時,發送完方法就返回了,并不等待對方回應,而是在接收到對方的數據時產生一個事件,讓應用程序有機會處理.
Sgs proxy
sgs允許任何支持tcp通信的客戶端都能連接上,但有一個問題: 瀏覽器訪問不了,現在的瀏覽器支持XmlHttpRequest,在瀏覽器上不刷新頁面的前提下可以使用http協議和服務器交換數據,但不支持tcp,而現在web game 發展很快,有沒有可能讓瀏覽器上基于javascript 的程序能夠和sgs 通信,享受sgs 的強大功能呢?這就是這個項目開發的初衷.
Sgs proxy 的基本思路是在web server創建一個代理,每個瀏覽器客戶端和代理交互,代理再和sgs server 交互.sgs proxy 負責所有的連接創建,銷毀,管理,調用等工作,應用程序只需要設計通過tcp連接sgs server的協議,瀏覽器和web server之間的協議,然后實現并注冊一個轉換接口,在瀏覽器中就能夠象擁有tcp連接一樣,連接到sgs server上.下面是這個系統的結構圖:
如圖,sgs proxy 作為一個web app 運行在java web server 上(例如tomcat),每個瀏覽器可以通過sgs proxy 連接到 sgs server 服務器組中的任何一個節點,在連接之后,sgs proxy 負責管理連接,后續的通信都通過同一個tcp連接進行,直到連接斷開(客戶端主動logout,或者服務器將客戶端踢出).在sgs proxy 這一層,只負責創建和管理到sgs server 的連接,其它所有的應用程序狀態都存儲在sgs server上.所以sgs proxy 這一層可以根據需要,動態添加新的web server.其它支持tcp通信的平臺則直接通過tcp連接到sgs server 服務器組的節點.
Sgs proxy 通信模型:
由于與 sgs server 的通信本質上是異步的事件驅動的通信,所以在sgs proxy 上,為每個瀏覽器客戶端創建了事件隊列,當有事件到達,并且目前瀏覽器客戶端沒有連接到web server時,就將事件緩存到隊列中,瀏覽器客戶端定時執行輪詢,在每一次輪詢中,sgs proxy 負責將所有的事件對象轉換為瀏覽器能夠理解的格式,并返回.另外考慮到瀏覽器和web server通信模型是請求/響應方式,所以sgs proxy 實現了對這種通信方式的支持,在每次瀏覽器請求sgs proxy時,都附帶一個標志,表示當前的請求是否為同步請求,如果是同步請求,則當前的請求消息發送到sgs server 后,并不立即返回,而是等待sgs server返回一個事件(實際應用中,sgs proxy 和sgs server 應該是部署在同一個局域網中,所以sgs proxy 和sgs server之間通信應該不會有較大的延遲),直到sgs proxy 返回一個事件后,sgs proxy 將此事件立即傳遞給當前正在等待的瀏覽器客戶端,不再放到事件隊列中.對于應用協議被設計成為請求/響應方式的應用程序來說,使用這一特性在瀏覽器端可以獲得更好的效果.相反,如果是異步請求,消息發送到sgs server 后,瀏覽器就立即返回了,所有的事件處理放到了下一次輪詢中進行.缺省的輪詢間隔為5秒,此參數可調,也可以程序主動執行輪詢操作.輪詢間隔長一些,有助于減輕web server的負擔,但瀏覽器端的實時通信效果就下降,反之可以讓瀏覽器更像實時的連接和通信,但增加了web server 的負擔.
目前在jetty和tomcat中雖然有對 comet 的一定程度的支持,但使用的都是私有的技術,考慮到兼容性的問題,所以未使用comet實現,而使用了輪詢作為模擬持久連接的手段,由于每次輪詢操作都是處理內存中的事件隊列,并且傳輸的都是少量的json數據,所以每次輪詢的開銷并不是很大.
在servlet3.0的規范中提到了對comet的支持,所以在servlet3.0實現之后,會考慮增加comet的通信方式.
目前實現功能
目前sgs proxy 基本上實現了sgs server 的所有操作和事件類型包括:
支持的操作包括:
l 登錄
l 登出
l 向server 發送消息
l 向channel 發送消息
l 輪詢操作(這是sgs proxy為了模擬實時的消息獲取而設計的,非sgs server 的操作)
支持的事件類型包括:
l 登錄成功
l 登錄失敗
l 連接斷開
l 加入channel
l 退出channel
l 接收到服務器消息
l 接收到Channel 消息
數據格式:
瀏覽器和web server 之間通過json格式傳遞數據,應用程序的數據通過一個javascript 對象數組的形式構造,傳遞到web server 后,此對象數組被映射成為一個List<Map>類型的對象. 具體的數據項由應用程序負責,應用程序需要實現一個對象到字節流(ByteBuffer) 轉換的接口,sgs proxy 和sgs server之間的通信使用了sgs server 定義的標準方式—ByteBuffer,對于從 sgs server 接收到的消息,應用程序需要實現一個ByteBuffer 到應用程序對象的轉換接口,最后對象被轉換為javascript 的對象數組返回給瀏覽器.
如何開始:
Sgs proxy包含了一個瀏覽器版本的 darkmud 客戶端,用以驗證各項功能,以下地址下載darkmud服務器,darkmud swing client,以及sgs proxy, 運行darkmud 服務器后,同時用swing client 和sgs proxy 中包括的瀏覽器客戶端連接到darkmud,觀看效果.具體的使用說明可以查閱下載包中的readme 文檔.
下載地址:
這是瀏覽器連接上darkmud之后的截圖:
之后可以從 svn 中checkout 代碼,實際使用
本項目以lgpl的協議發布.
如果有什么問題和建議,可以聯系:
袁云昌
qq: 517655261