QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3620|回复: 0

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

[复制链接]
发表于 2008-12-11 08:58:26 | 显示全部楼层 |阅读模式
为了大家可以更容易的利用libeva来实现自己的QQ客户端,
我把发送消息和接收消息的部分简单的说一下,给一点例子。

这里假设网络部分已经处理好了。

先说一下发送的流程:
客户端发一条消息, 服务器回复,表示收到你发的消息。

接收流程:
服务器发给你一条消息, 你如果可以正确解析,则发给服务器一个返回,表示你正确收到了。


发消息,就没什么说的了,大致代码如下

  1. SendTextIMPacket *IMPacket = new SendTextIMPacket();
  2. IMPacket->setReceiver(123456); // 对方的QQ号,123456
  3. IMPacket->setAutoReply(false); // 是正常聊天消息,不是自动回复
  4. IMPacket->setMessage("你好");  // 消息内容, 是个std::string 类型,这个字符串一定要是GB编码的,GBK, GB18030都可以。

  5. //这里是发送前处理
  6. int len = 65535;
  7. char *buf = new char[len];
  8. IMPacket->fill(buf, &len);   // 填充最终发送内容
  9. //然后发送 buf, 长度就是len。
复制代码
收消息是要注意, 每次收到消息,要发上给服务器发一个包,包内容是收到的包的前16个字节
这是告诉服务器,“我”收到你的消息了,否则,服务器会重复发多个。

  1. //packet是你收到的那个来自服务器的消息,通过getReplyKey这个方法
  2. //可以得到回复用的前16个字节, 然后设置要回复的包序号,然后发送
  3. ReceiveIMReplyPacket *packetReply = new ReceiveIMReplyPacket(packet->getReplyKey());
  4. packetReply->setSequence(packet->getSequence());

  5. //这里是发送前处理
  6. int len = 65535;
  7. char *buf = new char[len];
  8. IMPacket->fill(buf, &len);
  9. //然后发送 buf, 长度就是len。
复制代码
要注意的是,每次发送给服务器一条消息,服务器总回给一个返回,表示
成功收到还是不成功,如果收不到,需要客户端重新再发一次,确保服务器正确
地收到。下面就会说到。


下面是收消息的处理

  1. // 收到字节后首先判断是什么命令
  2. // rawData 就是收到的字节,len是收到的字节数目
  3. InPacket *in = new InPacket((unsigned char *)rawData, len);

  4. //然后根据命令,来执行不同的部分,来解析数据

  5. if (in->getCommand() == QQ_CMD_RECV_IM ){ // 如果是有消息到来
  6.         ReceiveIMPacket *packet = new ReceiveIMPacket();
  7.         packet->setInPacket(in);
  8.         if(packet->parse()){   // 初步解析消息头,如果成功, 发一个确认收到的消息给服务器
  9.             ReceiveIMReplyPacket *packetReply = new ReceiveIMReplyPacket(packet->getReplyKey());
  10.             packetReply->setSequence(packet->getSequence());
  11.             connecter->append(packetReply);  // 这里换成你自己的发送代码
  12.         }else
  13.             return;  // 否则忽略就可以了。
  14.             
  15.         switch(packet->getIMType()){  // 判断具体聊天消息类型
  16.         case QQ_RECV_IM_TO_BUDDY:     // 来自好友的消息
  17.         case QQ_RECV_IM_TO_UNKNOWN:{  // 来自陌生人的消息, 好友和陌生人的消息格式是一直的,都是普通文本聊天消息
  18.                 NormalIMBase *base = new NormalIMBase(packet->getBodyData(), packet->getBodyLength());
  19.                 base->parseData();  
  20.                 switch(base->getNormalIMType()) // 判断是普通聊天消息,也可能是文件传输的一些请求
  21.                 {
  22.                 case QQ_IM_NORMAL_TEXT:{ // 如果是普通聊天消息
  23.                         ReceivedNormalIM * received = new ReceivedNormalIM();
  24.                         received->setNormalIMBase(base);
  25.                         received->parseData();
  26.                        
  27.                         // 现在消息全在received里了
  28.                         // 你可以通过ReceivedNormalIM 类的方法来取消息内容,字体信息 等等.
  29.                         delete received;
  30.                         }
  31.                         break;
  32.                 default: // 否则,其它类型,不管它
  33.                         printf("Got a non-text msg, can't process it, ignore it\n");
  34.                 }
  35.                 delete base;
  36.                 }
  37.                 break;
  38.         default:
  39.                 printf("message code: 0x%4x -- sender:%d  -- Unknown\n",packet->getSender(), packet->getIMType());
  40.         }
  41.         delete packet;
  42. }
复制代码
注意可能libeva部分的代码有改动, 就是parse(), 以前好像是void型,
现在改成bool型了, 如果是void型, 不用判断, 直接发确认给服务器好了。

这里我只是简单说了一下,发送和接收, 尤其是接收,在QQ中会收到很多不同的聊天消息,
像群,认证什么的。 具体的参考api目录下的 evapacketmanager.cpp吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-4-26 16:37 , Processed in 0.045837 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表