广告位,联系QQ:910488011
当前位置: 首页 > Q协分析 > webqq入门协议-保持在线,心跳包,json解析,poll2性能,clientID生成
Q协分析
webqq入门协议-保持在线,心跳包,json解析,poll2性能,clientID生成
作者: admin  时间: 2012-07-02  点击: 16120

webQQ保持在线的请求又被俗称为心跳包,这个请求在webqq中非常特殊,而且意义重大。所有的消息通知,基本都是通过这个长长链接通知给客户端的。
请求地址:http://d.web2.qq.com/channel/poll2

请求方式:post



post数据:

r=%7B%22clientid%22%3A%2211558985%22%2C%22psessionid%22%3A%

228368046764001e636f6e6e7365727665725f77656271714031302e313

2382e36362e31313200000bc0000019a4026e040012b794306d0000000a

4078705668786c6e66556d000000289fd9dd6d0ea4aa39ce5620ed046d5

80658540f109018ee9d0015aa7ad4114613dd203926a34b46e3%22%2C%22

key%22%3A0%2C%22ids%22%3A%5B%5D%7D&clientid=11558985&psessi

onid=8368046764001e636f6e6e7365727665725f77656271714031302e

3132382e36362e31313200000bc0000019a4026e040012b794306d000000

0a4078705668786c6e66556d000000289fd9dd6d0ea4aa39ce5620ed046d

580658540f109018ee9d0015aa7ad4114613dd203926a34b46e3



post数据解码格式:

r={"clientid":"11558985","psessionid":"8368046764001e636

f6e6e7365727665725f77656271714031302e3132382e36362e313

13200000bc0000019a4026e040012b794306d0000000a407870566

8786c6e66556d000000289fd9dd6d0ea4aa39ce5620ed046d580658

540f109018ee9d0015aa7ad4114613dd203926a34b46e3","key":0,

"ids":[]}&clientid=11558985&psessionid=8368046764001e636f6e6

e7365727665725f77656271714031302e3132382e36362e313132000

00bc0000019a4026e040012b794306d0000000a4078705668786c6e6

6556d000000289fd9dd6d0ea4aa39ce5620ed046d580658540f10901

8ee9d0015aa7ad4114613dd203926a34b46e3


先说这个请求的各个参数含义。
clientid 即客户端ID,这个参数是由js生成,并没有基于什么参数生成,所以该参数可以固定可以随机。
此处给出标准clientid的c#算法:本帖隐藏的内容
http://www.qicq5.com/thread-15-1-1.html

psessionid,登陆成功后会返回。

登陆成功的cookie要带上,如果你不清楚哪个cookie是必须的,那么建议你全部带上。大多数的朋友在此出现问题都是cookie的问题,如果是c#,可以参考这个帖子去解决cookie的问题:本帖隐藏的内容
http://www.qicq5.com/thread-189-1-1.html

请求的返回:
这个请求服务器的返回是多种多样的,加好友的请求、加群请求、好友消息、群消息等都是通过这个这个请求返回给客户端。

返回中retcode参数指定一些状态,为0时表示有消息通知、为102时为没有消息通知,这两个状态都是正常状态。如果出错不同的错误会返回不同的状态码,121为掉线或者被客户端QQ顶掉时的状态码。

特殊性:
该请求为了一个长连接请求,如果服务器有消息推送给客户端,那么此请求会立刻响应,如果服务器没有消息通知,那么该请求会保持链接大概30秒-1分钟(这个时间我没有测试过)然后返回102状态码。

本帖隐藏的内容
有太多的朋友在纠结这个心跳包到底间隔多长时间发送一次,我也解释了太多次了。这个没必要间隔时间,webqq的异步请求里也是没有间隔时间的,最准确的做法是新开一个线程,死循环去请求这个链接。因为是持续性的请求,他并不会立马相应,会消耗一部分时间,所以对cpu不会造成什么负担。并且只有这样做才不会漏掉每一条消息。

返回消息呃分类和json
腾讯大部分产品的请求返回数据的格式都是json格式,很多朋友乐意使用字符串截取,也有朋友喜欢使用json,还有朋友喜欢正则。这都是个人爱好,什么顺手就用什么,没必要因为他是json格式就必须要使用json去解析它。当然这个请求使用json去解析数据会简单一些,并且大部分的json类库都会自动将Unicode编码转为明文。

对于c#这里介绍一个json类库及使用方法,其他语言本人不熟悉,还请各位看官百度一下。
c#的json类库大多是支持3.5以上的,当然2.0的也有,我在群共享传过。这里简单介绍一下System.Json.dll的使用方法。
System.Json.dll是第三方类库,文章末尾会传附件。限于篇幅,我直接上代码了,代码里包含对于心跳包常见类型的解析,大家看代码自己琢磨吧。本帖隐藏的内容
//try
//{
// JsonObject message = (JsonObject)JsonValue.Parse(result);
// if (message["retcode"].ToString() == "0")
// {
// foreach (JsonObject item in message["result"])
// {
// string type = item["poll_type"].ToString().Replace("\"", "");
// switch (type)
// {
// case "message":
// InitFriendMessageEvent(item);
// break;
// case "system_message":
// InitAddFriendEvent(item);
// break;
// case "group_message":
// InitGroupMessageEvent(item);
// break;
// default:
// break;
// }
// }
// }else if(message["retcode"].ToString() == "121")
// {
// if (OnUnLine != null)
// OnUnLine(user.Username);
// }
//}
//catch (Exception)
//{

//}








对于c#Unicode编码转明文,论坛已有代码,可以自己搜索一下




最后一个问题,掉线处理
webqq一般2天会掉一下或者由于某种原因掉线了,那么此请求会返回121状态码,判断此状态码,掉线后重登就可以了。