终于发现libpomelo2坑爹的bug了。伤不起。

当我尝试用libpomelo2连接lord of Pomelo时,发送登陆场景请求。然后,居然报decode失败。
遇到这个问题,是昨天晚上。为了解决这个问题,我从昨天11点多就开始找。找到现在,终于找到原因了。
显然ibpomelo2并没有做通解析protobuf的功能。
服务器返回来的PC_MSG_RESPONSE消息是没有route字段。
在pc_default_msg_decode函数中。也没有进行相关获取。导致protobuf的数据走json解析路径,导致decode失败。

解决方式。
每次request的时候,根据reqId保存对应的route。
response回来的时候,再根据reqId取回route,就可解决。
js版都是这样处理的。搞不懂ibpomelo2为什么出现这个问题。

然后,还有一个问题。
在static pc__msg_raw_t pc_msg_decode_to_raw(const pc_buf_t buf)函数
解析reqId的时候,服务端是这样处理的。
} while(m >= 128);
它居然这样处理,不知道什么逻辑。
} while(m & 0x80);

最后一个问题。
pc_request_with_timeout的时候,居然不返回reqId.
这可是C语言写的啊,难道要写无数的requestCB函数吗?C语言没有闭包函数诶。

标签: libpomelo2
linyouhappy 在 2015-10-7 07:09发布
linyouhappy 在 2015-10-7 07:11重新编辑 分享到 weibo
9 回复
#1 linyouhappy 2015-10-7 07:13 回复

7点多了。准备睡觉了

#2 {1} roytan 2015-10-7 11:09 回复

呵呵,你不要一会儿顶libpomelo2一会儿又吐槽啊^_^
期待你踩掉大部分坑,然后编译几个可用的平台库出来大家可以用
很奇怪为什么官方不把编译好的各个平台lib发布出来,方便一点不好么

linyouhappy 2015-10-7 15:21 回复

libpomelo2比较新的东西,还没有完工。搞lib不太好。而且功能也损失掉,因为libpomelo2封装了一个很好用的socket库,我见过很多socket库,都没有libpomelo2采用libuv封装的好。
只要libuv生成a文件就好。libpomelo2采用源代码导入。
如果只支持json,不要protobuf,可以编译成lib文件。

#3 {1} roytan 2015-10-7 11:10 回复

。。。你不是从晚上11点一直弄到早上7点吧 ???

linyouhappy 2015-10-7 15:22 回复

做游戏开发的,天天写上12小时以上代码,很正常啊。

#4 {1} roytan 2015-10-7 11:24 回复

刚刚又看了一下libpomelo2的h头文件,ping pong之类接口和事件还是没有。。。
建议你在移动网络环境下多测试一下

linyouhappy 2015-10-7 15:24 回复

ping pong实现,libuv的test里面有一个pingpong的例子。在libuv的test文件夹。libpomelo2引入了libuv库,可以直接用一下那个测试例子。

#5 linyouhappy 2015-10-7 20:45 回复

今晚尝试决解这个问题。发现PC_MSG_RESPONSE消息的protobuf解析被遗忘了。

#6 linyouhappy 2015-10-7 21:03 回复

解决代码:
在pr_msg.c文件

include "pc_pomelo.h"

pc_client_t* client=NULL;

//在这个函数上面加client变量,获取route用。
pc_msg_t pc_default_msg_decode(const pc_JSON* code2route, const pc_JSON* server_protos, const pc_buf_t* buf)

//在这个函数里面。
加入如下代码。
/* route /
if (PC_MSG_HAS_ROUTE(raw_msg->type)) {
。。。。。。。。
}
else
{
/
FIXME: for resp, we can not get route here, so just set it to NULL /
msg.route = NULL;
if (client!=NULL && msg.id>0)
{
QUEUE
q;
pc_request_t* req;
pc_mutex_lock(&client->req_mutex);
QUEUE_FOREACH(q, &client->req_queue) {
req= (pc_request_t* )QUEUE_DATA(q, pc_common_req_t, queue);
if (req->req_id == msg.id) {
if (msg.route!=NULL) {
pc_lib_free((char *)msg.route);
}

                int route_len=strlen(req->base.route);
                route_str = (char *)pc_lib_malloc(route_len+ 1);
                memset((char*)route_str, 0, route_len + 1);
                memcpy((char*)route_str,req->base.route, route_len);

                msg.route=route_str;
                break;
            }
        }
        pc_mutex_unlock(&client->req_mutex);
    }

}

然后在底部函数获取client。
pc_msg_t pr_default_msg_decoder(tr_uv_tcp_transport_t* tt, const uv_buf_t* buf)
{
pc_buf_t pb;
pb.base = buf->base;
pb.len = buf->len;
client=tt->client;

return pc_default_msg_decode(tt->code_to_route, tt->server_protos, &pb);

}

#7 linyouhappy 2015-10-7 21:06 回复

可以把pc_mutex_lock(&client->req_mutex);去掉。

#8 linyouhappy 2015-10-7 21:10 回复

今天终于扫清所有的技术障碍了。
一个人用pomelo+cocos2dx-js开发项目真不容易。

#9 wangxy 2015-10-8 09:54 回复

> 每次request的时候,根据reqId保存对应的route。
> response回来的时候,再根据reqId取回route,就可解决。
> js版都是这样处理的。搞不懂ibpomelo2为什么出现这个问题。

这个问题讨论过,由于原来协议的缺陷,resp回来并没有带route,造成的问题,你可以看一下以前的讨论

> 然后,还有一个问题。
> 在static pc__msg_raw_t pc_msg_decode_to_raw(const pc_buf_t buf)函数
> 解析reqId的时候,服务端是这样处理的。
> } while(m >= 128);
> 它居然这样处理,不知道什么逻辑。
> } while(m & 0x80);

在m是一个8位的无符号整数的情况下,这两种方式是等价的,在js中,前一种方式较高效,在C中,下一种方式较高效

> 最后一个问题。
> pc_request_with_timeout的时候,居然不返回reqId.
> 这可是C语言写的啊,难道要写无数的requestCB函数吗?C语言没有闭包函数诶。

reqId 是内部使用的,不应该暴露出来的。不过pc_request_* 提供了一个void* 参数 ex_data, 这个参数可以在回调里面获取,你可以用这个参数干任何事

回到顶部