使LumaQQ.NET支持接收长消息

        之前的文章里说明了怎么让LumaQQ.NET发送长消息,这里我们看看怎么让LumaQQ.NET支持接收长消息。

        其实QQ的服务器在发送长消息时,是将其拆分成几个短的消息来发送的,这点在上一篇发送长消息时,大家已经能看出来了。那么怎么将几个短消息合并成一个长消息呢。

        这里主要是用到了NormalIM的TotalFragments和FragmentSequence两个属性,FragmentSequence表示这个是第几个分片,基于0的index,TotalFragments表示一共有几个分片。

        由于收到消息时,不一定是按照顺序接收到的(网络延迟等原因),因此我们定一个Dictionary来管理分片。

private static Dictionary<int, Dictionary<int, byte[]>> NormalLongTextDict = new Dictionary<int, Dictionary<int, byte[]>>();
 
        然后在接收到消息的事件里,进行判断和组装
void MessageManager_ReceiveNormalIM(object sender, LumaQQ.NET.Events.QQEventArgs<LumaQQ.NET.Packets.In.ReceiveIMPacket, OutPacket> e)
{
    if (e.InPacket.NormalIM.TotalFragments > 1)//如果是长消息的分片
    {
        Dictionary<int, byte[]> TextFragment;
        if (!NormalLongTextDict.ContainsKey(e.InPacket.NormalIM.MessageId))//如果字典里没有缓存这个消息id
        {
            TextFragment = new Dictionary<int, byte[]>();
            TextFragment.Add(e.InPacket.NormalIM.FragmentSequence, e.InPacket.NormalIM.MessageBytes);//将分片加入以分片id为标示的分片缓存
            NormalLongTextDict.Add(e.InPacket.NormalIM.MessageId, TextFragment);//将分片缓存加入以消息id为标示的消息缓存
        }
        else
        {
            TextFragment = NormalLongTextDict[e.InPacket.NormalIM.MessageId];//取出分片缓存
            TextFragment.Add(e.InPacket.NormalIM.FragmentSequence, e.InPacket.NormalIM.MessageBytes);加入新的分片
            NormalLongTextDict[e.InPacket.NormalIM.MessageId] = TextFragment;放回消息缓存
        }
 
        if (TextFragment.Count == e.InPacket.NormalIM.TotalFragments)//如果所有分片都已经接收完毕
        {
            List<byte> LongTextBytes = new List<byte>();
            string LongText = "";
            for (int i = 0; i < TextFragment.Count; i++)
            {
                LongTextBytes.AddRange(TextFragment[i]);合并byte数组
            }
            LongText = Encoding.GetEncoding(QQGlobal.QQ_CHARSET_DEFAULT).GetString(LongTextBytes.ToArray());转为文字字符串
              NormalLongTextDict.Remove(e.InPacket.NormalIM.MessageId);//删除缓存
              e.QQClient.MessageManager.SendIM(e.InPacket.NormalHeader.Sender, string.Format("我收到你的消息:{0}", LongText);
        }
    }
    else
    {
        WriteError("收到好友:{0}/{1} 发来的信息:{2}", e.InPacket.NormalHeader.Sender, Nick, AnalyCustomFace(e.InPacket.NormalIM.MessageBytes));
        e.QQClient.MessageManager.SendIM(e.InPacket.NormalHeader.Sender, string.Format("我收到你的消息:{0}", e.InPacket.NormalIM.Message));
 
    }
 
 
}
posted @ 2008-04-22 17:21 蓝色的风之精灵 阅读(1554) 评论(9)  编辑 收藏 网摘

  回复  引用  查看    
#1楼2008-04-22 17:57 | 阿不      
这个功能会直接做到内部去,
只有收到完整信息后才会触发相关事件。

  回复  引用  查看    
#2楼[楼主]2008-04-22 18:02 | 蓝色的风之精灵      
呵呵,这样最好~~
  回复  引用  查看    
#3楼2008-04-22 18:15 | 侯垒      
呵呵,这个好呀!
  回复  引用  查看    
#4楼2008-04-22 19:09 | overred      
你也可以把这些消息的接受时间打印出来(精确点)
几乎是同时的

飞信也这样。。几乎没区别

  回复  引用  查看    
#5楼2008-04-22 22:18 | 随风逝去(叶进)      
很好啊! 很强大啊!
  回复  引用  查看    
#6楼[楼主]2008-04-23 18:23 | 蓝色的风之精灵      
@overred
如果接受到的消息比较多比较频繁,就分不清是不是同一条消息了。

有一次我见到过分段消息到达不同时,中间一段晚了1秒……所以还是根据MessageID来分辨比较好~

  回复  引用    
#7楼2009-01-09 15:38 | 强大[未注册用户]
怎么越看越 象给 FLASH 上面的东东 添加程序啊!



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1165919




相关文章:

相关链接: