阿不

不抛弃,不放弃

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  158 随笔 :: 0 文章 :: 2109 评论 :: 70 引用

使用DotMSN来开发MSN机器人,机器人在一段时间里如果没有接收到任何会话请求时,经常会自动断线。而且这个连接断线是没有响应任何事件的,而且Connected是True,Owner.Status也是正常的,这不得不让人头痛啊。

经过查阅一些资料,发现只要定时向MSN服务器发送Ping命令,以保持客户端与服务器的连接,即可解决这个问题。但是问题是DotMSN里提到的SendPing()方法它并没有提供啊!?可以查找到MSNP协议里头,发送Ping命令是通过PNG\r\n。但是如何来发送是一个问题了。

最初的想法是构建一个NSMessage对象,由NameserverProcessor.SendMessage方法来发送。使用代码如下:

   1: void SendPing()
   2:         {
   3:             NSMessage message = new NSMessage("PNG\r\n", new string[] {  });
   4:             messenger.NameserverProcessor.SendMessage(message);
   5:         }

但是每当我发送一个Ping命令后,虽然PingAnswer事件会被触发,也就是服务器有响应了,Ping命令发送成功。但是同时我的登录也会被服务器踢出,SignedOff事件被触发了。在仔细查阅了NSMessage信息对象的定义后发现,这个对象构建的发送字节除了命令本身还会有空格,TransactionID,还有参数,最后才会加上\r\n。而Ping命令本身是不需要任何参数的,整个命令就只有PNG\r\n。解决办法是不是可以构建一个专门的PingMessage对象来表示Ping命令,这个对象很简单:

   1: public class PingMessage : XihSolutions.DotMSN.Core.NSMessage
   2: {
   3:     public override byte[] GetBytes()
   4:     {
   5:         return System.Text.Encoding.UTF8.GetBytes("PNG\r\n");
   6:     }
   7: }

重新修改一下SendPing方法:

   1: void SendPing()
   2: {
   3:    messenger.NameserverProcessor.SendMessage(new PingMessage());
   4: }

登录后,发送一个Ping命令试试,PingAnswer事件触发了,用户不会被踢出了。这表示Ping命令发送成功了。接下来所要做的就是创建一个Timer对象,由Timer对象来控制定时向服务器发送Ping命令,以保证机器人客户端正与服务器保持连接。

注意,目前我的测试是在之前连接断开间隔时间内,甚至更长一些,机器人始终保持连接。不保证全天候都能保持连接,但是其它的断开原因可能需要不同的处理方法。

阿不 http://hjf1223.cnblogs.com
posted on 2008-01-10 09:31 阿不 阅读(2940) 评论(21)  编辑 收藏 所属分类: .Net相关技术经验总结

评论

#1楼  2008-01-10 10:23 李华星      
学习了一下
  回复  引用  查看    

#2楼  2008-01-10 11:04 Anders Cui      
收藏
  回复  引用  查看    

#3楼  2008-01-10 12:50 overred      
可以做win服务
  回复  引用  查看    

#4楼  2008-01-10 13:19 wenanry      
好文章,学习了
  回复  引用  查看    

#5楼  2008-01-10 17:50 jirain [未注册用户]
我也为这个头痛过,不过已经解决了,没有用楼主说的ping的方法,设置了一个线程,隔一段时间重新设置 messenger.Nameserver.Owner.Status = PresenceStatus.Online 就可以了

  回复  引用    

#6楼 [楼主] 2008-01-10 18:16 阿不      
@jirain
这应该也是个办法,我也有想过这样做。其实从原理上就是定时让它与服务器进行一次连接。但我测试的时候是失败的,所以才会用这种办法
  回复  引用  查看    

#7楼  2008-01-10 21:56 鞠强      
mark
  回复  引用  查看    

#8楼  2008-01-10 23:52 4的 [未注册用户]
有点意思
  回复  引用    

#9楼  2008-01-11 09:55 亚历山大同志      
让DuDu来说说如何解决的撒,闪存那个还常常死掉么?
  回复  引用  查看    

#10楼 [楼主] 2008-01-11 10:30 阿不      
@亚历山大同志
不知道他是否看到了?不过内存的机器人好像不是他开发的。
  回复  引用  查看    

#11楼  2008-01-12 22:48 浴盆      
哈原来你已经对这个问题写了文章了,真是太感谢了
我的DOTMSN必须是一直在线的,用你这个方法应该也可以吧?
  回复  引用  查看    

#12楼 [楼主] 2008-01-15 19:46 阿不      
@浴盆
是可以的。
  回复  引用  查看    

#13楼  2008-01-19 20:27 随风逝去      
刚好用来解决问题!
  回复  引用  查看    

现在的问题是这样的,偶尔提示下面的错误,不知道具体是为什么

未处理的“System.ArgumentOutOfRangeException”类型的异常出现在 mscorlib.dll 中。

其他信息: 长度不能小于 0。

是封装的类库有问题吗,还是其他问题
  回复  引用    

#15楼 [楼主] 2008-01-29 16:06 阿不      
@北京朋友
是会有这样的错误提示,它是由于Int.Parse(str) str的长度超过了int能表示的范围了。这个错误本身并不会影响到它的正常运行。
  回复  引用  查看    

#16楼  2008-02-20 13:23 侯垒      
学习了,顶一个。

  回复  引用  查看    



该文章已转到

http://www.leadnt.org/a/a.asp?B=21&ID=14&AUpflag=1&ANum=1
  回复  引用    

#18楼  2008-04-08 17:44 yuping [未注册用户]
楼主,你在用DotMsn 开发机器人的时候发生过内存问题么。当程序长时间运行(一个晚上时)所占用的内存就会大幅增加 ,
所用的内存和时间成正比。 我觉得这是DotMsn本省的问题,不知道你碰过没有,有没有解决方案。有的话和根我邮箱联系。
  回复  引用    

#19楼  2008-05-10 15:31 stormmxj [未注册用户]
看了你的文章对我很有帮助,
但是我用dotmsn怎么好像发送不了长字符串,这是什么原因呀?
楼主知道怎么解决吗?
希望楼主多指教!
  回复  引用    

1: void SendPing()
2: {
3: NSMessage message = new NSMessage("PNG\r\n", new string[] { });
4: messenger.NameserverProcessor.SendMessage(message);
5: }


void SendPing()
2: {
3: messenger.NameserverProcessor.SendMessage(new PingMessage());
4: }

请问楼主,这两个方法写在那个类里啊
  回复  引用    

#21楼 [楼主] 2008-06-19 08:56 阿不      
在你的使用类当中建议一个Timer,在Timer的回调事件中执行。
  回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      


相关链接: