pomelo c tcpclient 断开连接断开之后会收到什么消息或者通知一类的东西吗

pomelo 连接转发 - CSDN博客
componets:
& & & &connector 处理连接默认使用socketio
& & & &server 处理connector转发过来的msg,调用对应的handle
& & & & session 保存客户端的连接信息,生成用于后端使用的BackenSession
connection 保存连接的统计信息
connector是核心,在start的时候会获取其他三个组件,作为自己的一个变量使用,在afterstart时候,会对connectorserveice绑定connection消息
connection的消息流程:
& & httpserver接受upgrade消息,发送connection消息到websocket,然后转发给在hybrid的wsprocessor中,
switcher在初始化的时候就调用了
this.wsprocessor.on('connection', this.emit.bind(this, 'connection'));
& this.tcpprocessor.on('connection', this.emit.bind(this, 'connection'));
把wsprocessor的消息转发给了switcher,而switcher把消息在connector中进行处理了。
两个注意:
1:clientsocket在switcher中转发的时候,被包装成HybridSocket了,注意区别
2:之所以存在switcher,是为了处理tcp和ws连接,不同的连接最终都变味HybridSocket
connetor对connection消息的处理:
会调用connection组件,保存增加连接信息
调用session组件,产生session
对HybridSocket添加消息绑定,在接受message消息的时候,调用handleMessage,将session转化为后端session,转给server组件的globalHandle进行处理,处理的结果在回调函数中,作为resp,调用send函数,反馈给客户端
server组件对message的处理:
首先从msg中分析路由信息,调用parseRoute(msg.route);
然后调用过滤器,beforeFilter(true, self, msg, session, dispatch);
如果过滤通过,调用分发函数dispatch
在分发中,如果路由指向的服务器类型是当前服务器,调用doHandle,进行本服务器的handle调用,如果是其他服务器,调用doForward,通知其他服务器的handle调用,最终在回调中,把结果发个客户端。后台日志显示处理很快,但是客户端超过10秒未接收到消息 - Pomelo Club
后台日志显示处理很快,但是客户端超过10秒未接收到消息
客户端发过来一个请求,后台pomelo.log显示从handleMessage到send message的时间间隔不超过1秒,但是客户端那边却是超过10秒都未收到消息。客户端是安卓,官方给出的链接的socketio和websocket都出现过这种问题。
另外再问个问题,如果客户端访问的很频繁,比如同一个连接一秒内访问了10次,而服务器由于网络或一些其他原因,会不会出现如下错误:服务器先处理返回了第二次请求,然后才返回第一次请求,这时候客户端会不会把第二次请求的结果放在第一次请求上来处理,客户端和服务器之前的请求是不是有自带了标示来防止出现这情况。
不是每次请求都有回调嘛
不是每次都出现客户端长时间未收到返回信息的情况
@ 我们也遇到过这种问题
请求的处理好像没有一个超时机制,有时候服务进程在处理的过程中挂了,客户端就一直在哪里等待起,如果客户端设置一个超时时间,超过这个时间就给用户一些交互性的提示,但有可能服务端卡,处理得慢,过了这个时间后它又返回回来了。
@ 目前客户端的机制就是超过10就做一些善后的处理,能知道这个时间是耗在哪里吗,日志只能看出后台处理的时间,都不到一秒,其他那么多时间都不知道跑哪里去了
@ 这个不是时间耗在哪里,我这几天一直在头痛这个问题,大概有几个原因,但具体原因还得看仔细代码:
自己的业务逻辑问题,处理时间过长
进程死掉了,uncaughtException或者nodejs都没捕获进程直接崩溃
自己的代码不严谨导致uncaughtException,如变量不存在
闭包内存问题,函数递归调用自己导致栈移除
pomelo框架RPC调用失败,
pomelo框架的其它异常导致进程死
在app中捕获uncaughtException可以看到异常栈,但5,6具体原因我也搞不明白,反正能看到许多pomelo中出现的异常。
也有说跟node的版本有关系,
@ 还有些日志也看不到,进程也在,但就是没有返回
@ 之前出现问题的时候,我看pomelo.log日志,从pomelo收到请求打印出来到处理完成next打印日志,两条日志的间隔不超过1秒,但客户端就是在10内没收到,完全没有任何头绪,在这两条日志的前后pomelo还有做了什么处理可能会耗时间吗
怎么没有开发团队来聊啊
我们与遇到这种情况,pomelo-flashclient客户端,在做压力测试的时候,调用order.orderHandler.save_order,调到几百次后服务端就没有返回了,导致前端一直挂起。即使我们前端搞个超时机制也不是办法啊
[ 12:59:32.938] [DEBUG] pomelo - 286: [/var/data/game/game-server/node_modules/pomelo/lib/components/connector.js] [connector-server-1] handleMessage session id: 5, msg: {&id&:1514,&route&:&game.gameHandler.game&.........
[ 12:59:32.982] [DEBUG] pomelo - 87: [/var/data/game/game-server/node_modules/pomelo/lib/components/connector.js] [connector-server-1] send message reqId: 1514........
上面这段是不是说明一次请求响应
[ 12:59:33.138] [DEBUG] pomelo - 286: [/var/data/game/game-server/node_modules/pomelo/lib/components/connector.js] [connector-server-1] handleMessage session id: 5, msg: {&id&:1515,&route&:&order.orderHandler.save_order&.........
上面这次请求后就再与没有看到send message reqId: 1515了,
这种问题怎么查?
还有就是有时候日志收到请求,但是没返回,我不知道是不是又是rpc调用超时,以前有遇到过提示“timer not exists”,但那时在webstorm上看到,现在部署到服务器之后,没有看到任何这个错误,我看了下,这个错误的输出方式是console.log,是不是就不会输出到日志,即使我在日志配置里面已经配置上了&replaceConsole&: true
木有人理我们,还的自己慢慢查了。看看forward里面有没有相应的日志
我有的是最新的0.9,会不会是新加的rpc超时机制的问题呢?
我目前用的是0.9.3,还会出现
客户端保存requestId及对应的回调, 后面请求到消息返回都会带上requestId, 因此不会处理错。
你说的客户端没收到消息的问题, 一般都是网络引起的,要根据业务逻辑决定是重试还是丢弃。
是的,有requestID,我现在发现pomelo日志中中有handleMessage session id: 不有对应的 send message reqId:
你说的网络问题出现在哪里呢?后端服务器之间的rpc?我们如何根据业务逻辑决定是重试还是丢弃?我们不知道请求到底是彻底的死了还是后端还在处理过程中。
给点意见吧
pomelo.log
[ 11:11:06.040] [DEBUG] pomelo - 286: [/var/data/game/game-server/node_modules/pomelo/lib/components/connector.js] [connector-server-1] handleMessage session id: 1, msg: {&id&:824,&route&:&order.orderHandler.save_order&,&body&.......
forward-log-order-server-2.log
[ 11:11:06.042] [DEBUG] forward-log - 43: [/var/data/game/game-server/node_modules/pomelo/lib/common/remote/backend/msgRemote.js] backend server [order-server-2] handle message: {&id&:824,&route&:&order.orderHandler.save_order&........
[ 11:11:06.096] [DEBUG] pomelo - 60: [/var/data/game/game-server/node_modules/pomelo/lib/modules/masterwatcher.js] masterwatcher receive remove server event, with server: order-server-2, type: order
上面是日志片段,pomelo成功forward到order-server2, 但接着order-server2被remove掉了,看日志order-server2中确实有uncaughtException。
这个时候怎么让客户端知道后端有异常发生了?就像http请求返回一个500一样?
@ 我的做法是所有的方法内都加入try catch,然后在catch内next错误码给客户端,我今天把rpc超时时间配长,配为20秒之后,好像没出现后台没返回的情况,不过今天比较忙,没做认真测试,明天我测下看看情况
@ 异步的try不到啊
@ 就像pomelo锁提议的那样,每个回调函数的第一个参数都是error
* @param sql
* @param args
* @param cb
* @param dbClient
dbUtils.delete = function (sql, args, cb, dbClient){
log.debug(sql);
dbUtils.buildDBClient(dbClient).query(sql, args, function(err, res){
log.error(&delete [& + sql + &] faild! & + err.stack);
utils.invokeCallback(cb, err, res.affectedRows);
handler里面就可以如下处理
leaguerService.findByUserAccount(msg.uid,function(err,leaguer){
requestUtils.nextError(err,msg,session,next);
} else if(leaguer == null){
next(null, {
code: Code.LEAGUER.NOT_EXIST,
msg: &会员不存在&
} else if(leaguer.password != encryptUtils.md5(msg.oldPassword)){
next(null, {
code: Code.LEAGUER.PASSWORD_ERROR,
msg: &旧密码不匹配&
leaguer.password = msg.newP
leaguerService.modifyPassword(leaguer);
requestUtils.nextSuccess(msg,session,next);
catch(e) {
log.error(&userApi.auth.modifyPassword exception & + e.stack);
requestUtils.nextError(e, msg, session, next);
我测过,如果在回调函数里面出现类似于 Cannot read property &xxxx& of undefined,catch都是能捕获的到的
@ 这个提议在哪里能看到 你代码中的requestUtils是自己写的还是pomelo的
@ 忘记了,也许是nodejs提议的,但这确实是个好习惯,pomelo的demo里面也都是这样做的,requestUtils是我自己写的,代码如下:
* 执行NEXT错误
* @param msg
* @param session
* @param next
requestUtils.nextError = function(err, msg, session, next) {
next(err, {
code: Code.FAIL,
msg: Message.ERROR
* 执行NEXT成功
* @param msg
* @param session
* @param next
requestUtils.nextSuccess = function(msg, session, next) {
next(null, {
code: Code.OK,
msg: Message.SUCCESS
我返回的结果都是以以下规范
code: 200, //自定义结果码以1000起,1000以内的保持跟http结果码一样,比如成功是200
msg: &结果提示&,
data : { //如果有其它返回数据,则都放在data里面,没有就不需要data
@ 服务端没有响应的问题解决了吗?
@ 我把rpc调用超时的时间调大了,现在就还没发现这种情况
app.set(&proxyConfig&, {
timeout: 20 * 1000 //rpc超时时间
@ 我们一些进程占用内存高达1.5G,达到nodejs的内存要求极限了,你们有没有这种情况,怎么处理的,分享点经验嘛
@ 目前没有,毕竟还没正式上线,如果遇到这种情况,我觉得可以考虑加服务器
@ 你们有没有遇到mysql执行sql 很慢的情况,我现在发现有时候处理整个请求很慢,最大都达到20秒了,通过日志查看,发现是在mysql执行sql的时候耗了很长的时间,其他的,包括通过连接池获取mysql连接对象,都很快
@ 我们用的mongodb&&&& &&&&&&
&& &&&&&&&&&&&&&&
版权所有 鲁ICP备号-4
打开技术之扣,分享程序人生!请教pomelo android client的一个小问题 - Pomelo Club
请教pomelo android client的一个小问题
您好,我服务器端是用nodejs+socket.io写的,ip是127.0.0.1,端口是3000,监听一个news事件,
socket.on(&news&, function (data) {
//do something
android端用rm(route, msg);发送信息,route填什么呢?我一开始填的&/&后来换成是&news&,结果什么也收不到.调试程序在Protocol.java return bt2Str(arr, 0, arr.length) +处返回 ??????127.0.0.1:3000/{&timestamp&:0,&news&:&Hello Server,I am Android&}
前面这些??????是什么?
15:01重新编辑
虽然这个android客户端底层是socket.io,但是这个客户端是对pomelo的socket.io版本进行支持的,所以你服务端要用pomelo进行开发,这个route是pomelo前端服务器地址,你可以看看pomelo wiki。
本人现在在学习客户端是andorid,服务端是pomelo ,能给个源码吗?但不是很懂,麻烦发到邮箱里。谢谢!!
@ 本人现在在学习客户端是andorid,服务端是pomelo ,能给个源码吗?但不是很懂,麻烦发到邮箱里。谢谢!!
@,你好,请问一下libpomelo你是怎么用android NDK编译过的?貌似libuv用android NDK编译无法通过啊?
好吧,我看错了,貌似你用的是android client...不是c client
使用, web客户端连接成功,Android客户端可以连接,但调用request, 服务器显示[ 16:28:56.586] [ERROR] console - rpc server process message error: TypeError: Cannot read property &namespace& of undefined,请问会是什么原因?pomelo&的一些监控和维护插件(工具)
提供了非常多的插件,可以方便我们日常对其的一些操作和开发工作,同样的我们也可以自己开发一些定制的插件让其伴随整个POMELO的生命周期运作(这里
不是要介绍如何制作POMELO插件),这里还是详细的介绍几种POMELO中比较有用的插件,通过这些插件的工作原理也可以让大家更加了解一些
POMELO的工作原理(不对之处非常感谢指证~),之前介绍过压力测试工具,今天介绍一下可以配合压力测试工具以及日常运维工作使用的服务器监测和命令
行工具。主要包含以下3方面
1 POMELO-CLI
2 POMELO-ADMIN
3 POMELO-ADMIN-WEB
首先来说第一个POMELO-CLI
这个其实不算POMELO的插件,只能算辅助管理POMELO的一个客户端命令行工具,通过这个工具我们不在需要到服务器程序的宿主机上去敲打
POMELO命令来对服务器进行一系列的操作了(停止,重启,热扩展,获取服务器信息等),工具内部包含了很多命令行可以使用,其本质的原理是通过控制台
连接上服务器的MASTER服务器然后远程发送命令给MASTER服务器让其控制所有的游戏服务器。
上面是一张非常经典的POMELO控制架构,MASTER管理着所有的服务器,那么我们只需要可以驱动MASTER就可以实现外部管理服务器了。是不是非
常方便?但是这样大家可能会有另外一个问题,这样安全吗?POMELO想到了这个问题,所以在大约0.6版本的时候POMELO加入了MASTER服务器
的权限控制,在服务器的CONFIG文件夹下有一个ADMINUSER文件,在里面可以设置允许登录MASTER服务器的用户名密码以及用户等级,通过这
样实现了对MASTER服务器的权限和安全性管理:
OK基本的都介绍完了那我们如何使用POMELO-CLI工具呢?详细的使用方式GIT上面都有描述了并且大家可以通过HELP来获取所有可以使用的命令,这里做几个简单的演示
(1)打开你的控制台
(2)输入npm install -g pomelo-cli
等待安装完毕
(3) 在控制台中输入连接命令
&&& pomelo-cli
-h 127.0.0.1 -P 3005 -u admin -p admin
可以看到在这条连接命令中我们需要输入MASTER服务器的地址端口,以及用户名密码&
看到如上画面就代表我们已经登录成功了,之后就可以使用CLI提供的一系列强大的工具了~
显示各服务器状态:
所有可以使用的命令
这里我就不对所有功能一一介绍啦~~大家可以自己使用体会哦~~(我觉得里面比较炫的功能主要还是热扩展服务器了!!非常实用的功能)
OK第二个我们来说说POMELO-ADMIN
pomelo-admin是可以提供对游戏各个服务器的各种数据进行实时监测和回报(CPU,内存,连接数等等),同时也可以自定义游戏逻辑数据的监测
(当前有多少用户在副本场景中,当前有多少用户在进行A任务,当前有哪些用户的帐号状态不正确)我们当然可以采用查询数据库和添加LOGGER来统计和监
测这些游戏逻辑数据,但是总是不够实时。有些情况比如A场景最大用户容量为200个,当超过200个用户的时候需要热扩展服务器,这个时候通过人工查询可
能已经为时已晚了,实时监测可以非常迅速的通知到运维人员当前的数据状态,同样的一些繁重的繁琐的日常查询工作除了使用跑数据库脚本以外也可以通过实时监
测来获取数据,当然好处还有许多,同样的相伴随的坏处就是会消耗一部分的服务器性能,所以还是要在各种条件之间平衡使用,这里不再深入讨论其好处和弊处
了,主要说下用法,因为POMELO-ADMIN的使用文档并不是那么的尽人意。
(1)首先使用pomelo-admin我们不需要做任何的安装工作,因为POMELO已经自带这个组件了
(2)pomelo本身自己实现了非常多的监控只需要在app.js中添加
app.configure(function () {
app.enable('systemMonitor');
就可以在所有已经配置的服务器上打开POMELO自身实现的一系列监控,其中包括(CPU,内存等等)
以下是POMELO注册已经实现的监控代码
虽然使用POMELO自带的监控非常简单,但是这里要注意的一点是,这些监控只有在linux环境下才可以使用,因为监控的底层实现都是直接调用了
LINUX命令,如果需要在WINDOW下实现类似的监控就需要自己实现啦(当然是调用WINDOW底层命令)~~具体如何实现自定义监控我会在接下来
OK我们现在来说说如何实现自定义的监控模块吧~假设有一个需求,需要实时监控当前连接服务器上的所有用户信息~(其实就是统计当前所有在线用户信息),
其实实现起来非常的简单,POMELO-ADMIN作为融入在POMELO框架中的插件,那么我们只需要按照约定实现插件回调就可以了.
(1)创建onlineUser.js文件
(2)构造部分
module.exports = function(opts)
&&& return new
onlineUser(opts);
var moduleId = "onlineUser";
module.exports.moduleId = moduleId;
var onlineUser = function(opts)
&&& this.app =
&&& this.type =
this.interval = 10;
构造部分没有什么好多说的主要就是按照POMELO框架约定好的方式构造就可以了,主要对几个参数做下解释
:监控模块标识,用于唯一标识该监控模块,非常重要的一个参数,要向该模块获取和发送数据都靠这个ID作为参数!特别是之后如果需要让外部程序获取该模块的监控数据也必须靠这个参数哦~~
this.app: 当前监控模块监控的服务器实例
this.type:pomelo-admin提供2种获取数据的方式,一种是PULL
一种是PUSH,顾名思义,PULL为拉方式,MASTER服务器主动从各个游戏服务器上拉取需要的监控数据,那么PUSH则是推了,就是反过来游戏服务
器向MASTER服务器推送监控数据,这个非常好理解
this.interval :每次push 和 pull 的时间间隔
(3)构造好了之后我们就可以在app.js中为服务器注册监控模块了
//配置监控
app.configure('production|development','connector|master', function
onlineUser = require("./monitor/onlineUser");
app.registerAdmin(onlineUser, {app: app});
这样就将监控在线用户的模块注册给了所有的连接服务器(K2中是3台)和MASTER服务器,为什么也需要注册给MASTER服务器呢之后的流程可以说明这一点(这里其实很绕,我觉得POMELO设计的不好。。)我们来看需要我们实现的3个回调
//收到游戏服务器PUSH数据回调,或者采用PULL的方式这个回调每次到达PULL间隔时会被调用
onlineUser.prototype.masterHandler = function(agent, msg)
//收到MASTER拉通知回调,或者采用PUSH方式每次到达PUSH间隔时会呗回调
onlineUser.prototype.monitorHandler = function(agent, msg)
//第三方程序调用获取监控数据接口时回调
onlineUser.prototype.clientHandler = function(agent, msg, cb)
我们来解释一下pull模式下的整个流程
完整的onlineUser代码
module.exports = function(opts)
&&& return new
onlineUser(opts);
var moduleId = "onlineUser";
module.exports.moduleId = moduleId;
var onlineUser = function(opts)
&&& this.app =
&&& this.type =
this.interval = 10;
onlineUser.prototype.monitorHandler = function(agent, msg)
sessionService = this.app.get('sessionService');
&&& var uidmap =
sessionService.service.uidM
allUserIds = Object.keys(uidmap);
&&& var uidInfos
= new Array();
&&& for(var i
var uid = allUserIds[i];
var infos = uidmap[uid];
var uidInfo =
&&&&&&&&&&&
uid:infos[0].uid,
&&&&&&&&&&&
frontendId:infos[0].frontendId,
&&&&&&&&&&&
userName:infos[0].settings.userName,
&&&&&&&&&&&
loginTime:infos[0].settings.loginTime
uidInfos.push(uidInfo);
agent.notify(moduleId, {serverId:agent.id,infos:uidInfos});
onlineUser.prototype.masterHandler = function(agent, msg)
agent.notifyByType("connector",moduleId);
agent.set(msg.serverId+moduleId, msg);
onlineUser.prototype.clientHandler = function(agent, msg, cb)
connectors = this.app.getServersByType('connector');
&&& var users =
new Array();
&&& for(var i
var co = connectors[i];
var key = co.id+moduleId;
var oneConnectorUsers = agent.get(key);
for(var j = 0;j
&&&&&&&&&&&
var user = s[j];
&&&&&&&&&&&
users.push(user);
returnData = {
result:users
cb(null,returnData);
这样我们就可以每隔10S获取一次当前在线用户数据了!因为有3台连接服务器所以一次会拉取三台服务器的数据
执行结果:
至此为止关于如何使用POMELO-ADMIN已经完全介绍完毕了,我们可以在LINUX
环境下利用其自带的模块来进行监控同样也可以按照自己的业务需求来自定义监控内容是不是很强大呢?因为是插件的形式,所以并不需要将记录的内容以及监控的
代码添加在业务逻辑的代码中,这点可以说是他最大的优点了,完全实现监控(统计)和业务逻辑分离!
最后POMELO-ADMIN-WEB
从名字就可以看出这个货是POMELO-ADMIN的一个补充,其实就是一个WEB网站,和POMELO-CLI同样的原理通过MASTER服务器获取POMELO-ADMIN的监控数据(还记得我们之前的实时监控数据缓存在了哪里吗?BINGGO!!!MASTER服务器中!!!)
node网站的部署我在这里就不多赘述了。。相信大家都会。只 需要到GIT上下载代码,然后NPM一下,最后在NODE
APP就可以了。。灰常简单!!通过他我们再也不需要将监控数据记录在LOG中去慢慢查了!!我们完全可以在可视化的WEB网站上面看到我们需要的实时监
通过配置文件配置需要连接的master服务器地址和帐号
QA环境是LINUX的我们通过WEB来看看POMELO自带的监控数据情况吧
SystemInfo模块:
ProcessInfo模块:
这里要注意的是虽然WEB页面上边栏中有许多选项,但是其实真正已经实现的可能只有部分,其余需要开发者按照自己的需求进行添加或者实现!
说道这里看的都是POMELO自带的一些监控数据那我们之前实现的监控在线用户的模块如何查看呢?
利用边栏中已经有的但未完全实现的Online User选项卡,
(1) 稍微修改一下WEB的源码
//看到没有我们将请求的模块ID改为了我们自定义的模块ID~~
window.parent.client.request('onlineUser', {type:"onlineUser"},
function(err, msg)
回到服务器的onlineUser代码文件中,实现第三个回调,将MASTER中按照KEY所缓存的三台连接服务器的在线用户数据取出然后CALLBACK就可以啦!
onlineUser.prototype.clientHandler = function(agent, msg, cb)
connectors = this.app.getServersByType('connector');
&&& var users =
new Array();
&&& for(var i
var co = connectors[i];
var key = co.id+moduleId;
var oneConnectorUsers = agent.get(key);
for(var j = 0;j
&&&&&&&&&&&
var user = s[j];
&&&&&&&&&&&
users.push(user);
returnData = {
result:users
cb(null,returnData);
来看一下结果吧~~
好了~~全讲完了~~主要希望可以帮到运维同学减少他们的学习成本~~~并且可以让大家更加了解一些POMELO的插件和其实现机制~~THXALL~~下次继续
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 httpclient断开链接 的文章

 

随机推荐