|
为了大家可以更容易的利用libeva来实现自己的QQ客户端,
我把发送消息和接收消息的部分简单的说一下,给一点例子。
这里假设网络部分已经处理好了。
先说一下发送的流程:
客户端发一条消息, 服务器回复,表示收到你发的消息。
接收流程:
服务器发给你一条消息, 你如果可以正确解析,则发给服务器一个返回,表示你正确收到了。
发消息,就没什么说的了,大致代码如下
[code:1]
SendTextIMPacket *IMPacket = new SendTextIMPacket();
IMPacket->setReceiver(123456); // 对方的QQ号,123456
IMPacket->setAutoReply(false); // 是正常聊天消息,不是自动回复
IMPacket->setMessage("你好"); // 消息内容, 是个std::string 类型,这个字符串一定要是GB编码的,GBK, GB18030都可以。
//这里是发送前处理
int len = 65535;
char *buf = new char[len];
IMPacket->fill(buf, &len); // 填充最终发送内容
//然后发送 buf, 长度就是len。
[/code:1]
收消息是要注意, 每次收到消息,要发上给服务器发一个包,包内容是收到的包的前16个字节
这是告诉服务器,“我”收到你的消息了,否则,服务器会重复发多个。
[code:1]
//packet是你收到的那个来自服务器的消息,通过getReplyKey这个方法
//可以得到回复用的前16个字节, 然后设置要回复的包序号,然后发送
ReceiveIMReplyPacket *packetReply = new ReceiveIMReplyPacket(packet->getReplyKey());
packetReply->setSequence(packet->getSequence());
//这里是发送前处理
int len = 65535;
char *buf = new char[len];
IMPacket->fill(buf, &len);
//然后发送 buf, 长度就是len。
[/code:1]
要注意的是,每次发送给服务器一条消息,服务器总回给一个返回,表示
成功收到还是不成功,如果收不到,需要客户端重新再发一次,确保服务器正确
地收到。下面就会说到。
下面是收消息的处理
[code:1]
// 收到字节后首先判断是什么命令
// rawData 就是收到的字节,len是收到的字节数目
InPacket *in = new InPacket((unsigned char *)rawData, len);
//然后根据命令,来执行不同的部分,来解析数据
if (in->getCommand() == QQ_CMD_RECV_IM ){ // 如果是有消息到来
ReceiveIMPacket *packet = new ReceiveIMPacket();
packet->setInPacket(in);
if(packet->parse()){ // 初步解析消息头,如果成功, 发一个确认收到的消息给服务器
ReceiveIMReplyPacket *packetReply = new ReceiveIMReplyPacket(packet->getReplyKey());
packetReply->setSequence(packet->getSequence());
connecter->append(packetReply); // 这里换成你自己的发送代码
}else
return; // 否则忽略就可以了。
switch(packet->getIMType()){ // 判断具体聊天消息类型
case QQ_RECV_IM_TO_BUDDY: // 来自好友的消息
case QQ_RECV_IM_TO_UNKNOWN:{ // 来自陌生人的消息, 好友和陌生人的消息格式是一直的,都是普通文本聊天消息
NormalIMBase *base = new NormalIMBase(packet->getBodyData(), packet->getBodyLength());
base->parseData();
switch(base->getNormalIMType()) // 判断是普通聊天消息,也可能是文件传输的一些请求
{
case QQ_IM_NORMAL_TEXT:{ // 如果是普通聊天消息
ReceivedNormalIM * received = new ReceivedNormalIM();
received->setNormalIMBase(base);
received->parseData();
// 现在消息全在received里了
// 你可以通过ReceivedNormalIM 类的方法来取消息内容,字体信息 等等.
delete received;
}
break;
default: // 否则,其它类型,不管它
printf("Got a non-text msg, can't process it, ignore it\n");
}
delete base;
}
break;
default:
printf("message code: 0x%4x -- sender:%d -- Unknown\n",packet->getSender(), packet->getIMType());
}
delete packet;
}
[/code:1]
注意可能libeva部分的代码有改动, 就是parse(), 以前好像是void型,
现在改成bool型了, 如果是void型, 不用判断, 直接发确认给服务器好了。
这里我只是简单说了一下,发送和接收, 尤其是接收,在QQ中会收到很多不同的聊天消息,
像群,认证什么的。 具体的参考api目录下的 evapacketmanager.cpp的文件内容吧。 |
|