聊天室是验证服务器最典型的例子,Pomelo的运行架构:

聊天室缓存架构如何实现 聊天室框架_json

在这个架构里,前端服务器也就是connector专门负责承载连接, 后端的聊天服务器则是处理具体逻辑的地方。 这样扩展的运行架构具有如下优势:

  • 负载分离:这种架构将承载连接的逻辑与后端的业务处理逻辑完全分离,这样做是非常必要的, 尤其是广播密集型应用(例如游戏和聊天)。密集的广播与网络通讯会占掉大量的资源,经过分离后业务逻辑的处理能力就不再受广播的影响。
  • 切换简便:因为有了前、后端两层的架构,用户可以任意切换频道或房间都不需要重连前端的websocket。
  • 扩展性好:用户数的扩展可以通过增加connector进程的数量来支撑。频道的扩展可以通过哈希分区等算法负载均衡到多台聊天服务器上。理论上这个架构可以实现频道和用户的无限扩展。

客户端主动触发

1.'gate.gateHandler.queryEntry':客户端从gate服务器查询一个connector服务器,gate给其回复一个connector的地址及端口号

2.'connector.entryHandler.enter':请求connector进程,首次进入时需要绑定对应的uid信息

3.'chat.chatHandler.send':用户发起聊天

客户端被动触发

pomelo.on('onAdd', function(data) {
 // ...enter触发
});pomelo.on('onLeave', function(data) {
 // ...leave触发
});pomelo.on('onChat', function(data) {
 // ...send触发
});

服务器的Handler

handler.queryEntry = function(msg, session, next) {
 // ...对应于'gate.gateHandler.queryEntry'
};handler.enter = function(msg, session, next) {
 / / .....对应于'connector.entryHandler.enter',并绑定session的closed函数onUserLeave
};handler.send = function(msg, session, next) {
 // .....对应于'chat.chatHandler.send'
};var onUserLeave = function(app, session) {
// .....用户离开
};

服务的Remote

ChatRemote.prototype.add = function(uid, sid, name, flag, cb) {
 // ...enter内部调用
};ChatRemote.prototype.kick = function(uid, sid, name) {
 // ...leave内部调用
};ChatRemote.prototype.get = function(name, flag) {
 // ...辅助函数,用于获得频道的用户列表
};

注意 在实现具体的Handler的时候,最后需要调用next,其中next的签名为 next(err, resp).如果没有出现错误,那么err为空即可;如果不是request请求,而是notify的话,则一样需要调用next,此时resp参数是不需要的,一般情况下,如果没有错误的话,就直接使用next(null)即可。

服务器配置信息在config目录下,现在我们只关注servers.json, master.json。master.json配置是master服务器的配置信息,包括地址端口号,servers.json配置具体的应用服务器信息。在配置文件中,分为development和production两种环境,表示开发环境和产品环境,我们在pomelo start后面可以通过-e可以指定使用哪个环境,更多帮助参见pomelo start --help