打印

有关libeva的使用说明-发送和接收消息

有关libeva的使用说明-发送和接收消息

为了大家可以更容易的利用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吧。

TOP