chatofpomelo的git地址在這里:
https://github.com/NetEase/chatofpomelo
當你啟動game-server和web-server之后,你就可以在web上進入一個聊天室進行實時聊天了。這里的實時聊天是使用了websocket技術,在網頁和服務器上建立了一個連接,本文的目的在於分析清楚下客戶端和服務端聊天的過程。
首先是客戶端(頁面)的js有:
jquery-1.8.0.min.js // 這個不用講了
pomeloclient.js // 這個是pomelo提供的js客戶端,主要客戶端和pomelo服務端交互的消息組織
socket.io.js //這個負責websocket的交互
client.js //這個是chat頁面特有的,頁面上的事件就在這個里面負責
pop.js // 這個是負責頁面的消息彈出框的顯示
客戶端和pomelo交互的流程是:
連接connector流程:
1 客戶端發送給服務端連接gate的消息
ws://127.0.0.1:3014
發送的消息內容如下:
"gate.gateHandler.queryEntry{"uid":"yejianfeng","timestamp":1360239219157}"
這個協議是pomelo自定義的協議,route + msg
2 服務端gate返回消息
"[{"id":3,"body":{"code":200,"host":"127.0.0.1","port":3050}}]"
這是個json數組,客戶端會對每個json數組進行processMessage
這里單講對於這個消息,有id,客戶端判斷是服務器的回復,需要回調之前已經注冊好的回調函數。
於是進行了下面的操作:
3 客戶端關閉當前與gate的連接:pomelo.disconnect()
4 客戶端根據gate返回回來的connector的host和port創建新的連接
"ws://127.0.0.1:3050"
5 向connector發送消息
"connector.entryHandler.enter{"username":"yejianfeng","rid":"test","timestamp":1360240686755}"
這個消息內容是route + Json(用戶名,roomid,時間戳)
6 connector向客戶端返回消息
"[{"id":3,"body":{"users":["yejianfeng"]}}]"
這個消息內容是告訴用戶這個room里面有哪些已經存在的用戶
7 客戶端收到這個消息知道注冊成功了,需要進入到了聊天頁面
所以將頁面變化到了聊天的頁面格式
發消息流程:
1 現在客戶端已經維持了一個與connector的ws長連接了
2 客戶端用戶寫好信息,調用回車鍵觸發js事件
3 客戶端在長連接上發送了消息:
"chat.chatHandler.send{"rid":"test","content":"hi","from":"yejianfeng","target":"*","timestamp":1360241187256}"
同樣是route + json(roomid,content,from,target,timestamp)
4 服務端返回:
"[{"route":"onChat","msg":"hi","from":"yejianfeng","target":"*"},{"id":9,"body":{}}]"
這個返回就和之前的都不一樣了,對於數組中的第一條
{"route":"onChat","msg":"hi","from":"yejianfeng","target":"*"}
這個會進行pomelo的回調:
pomelo.emit("onChat", {"route":"onChat","msg":"hi","from":"yejianfeng","target":"*"})
實際上就是調用事先注冊的onChat事件
onChat事件做的事是將消息顯示在歷史對話框中等操作
收消息流程:
1 現在客戶端已經維持了一個與connector的ws長連接了
2 服務端給客戶端發送消息
"[{"route":"onChat","msg":"hi","from":"yejianfeng2","target":"*"}]"
3 客戶端根據這個消息做了如下事情:
1> 顯示消息
2> 顯示彈出框pop
新用戶登陸離開流程:
1 現在客戶端已經維持了一個與connector的ws長連接了
2 服務端給客戶端發送消息
離開:
"[{"route":"onLeave","user":"yejianfeng2"}]"
加入:
"[{"route":"onAdd","user":"yejianfeng2"}]"
PS:
其實這樣看來這里還是有幾個地方是否可以考慮變化下:
與gate的交互其實可以不用使用websocket長連接,直接可以使用http,這樣能少了一次開銷