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,这样能少了一次开销