|
为了大家可以更容易的利用libeva来实现自己的QQ客户端,
我把发送消息和接收消息的部分简单的说一下,给一点例子。
这里假设网络部分已经处理好了。
先说一下发送的流程:
客户端发一条消息, 服务器回复,表示收到你发的消息。
接收流程:
服务器发给你一条消息, 你如果可以正确解析,则发给服务器一个返回,表示你正确收到了。
发消息,就没什么说的了,大致代码如下
- 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。
复制代码 收消息是要注意, 每次收到消息,要发上给服务器发一个包,包内容是收到的包的前16个字节
这是告诉服务器,“我”收到你的消息了,否则,服务器会重复发多个。
- //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。
复制代码 要注意的是,每次发送给服务器一条消息,服务器总回给一个返回,表示
成功收到还是不成功,如果收不到,需要客户端重新再发一次,确保服务器正确
地收到。下面就会说到。
下面是收消息的处理
- // 收到字节后首先判断是什么命令
- // 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;
- }
复制代码 注意可能libeva部分的代码有改动, 就是parse(), 以前好像是void型,
现在改成bool型了, 如果是void型, 不用判断, 直接发确认给服务器好了。
这里我只是简单说了一下,发送和接收, 尤其是接收,在QQ中会收到很多不同的聊天消息,
像群,认证什么的。 具体的参考api目录下的 evapacketmanager.cpp吧。 |
|