使用Dotmsn扩展Joymsg聊天机器人,使其同时支持QQ.MSN

先发图:

前几日刚刚公布了Joymsg的源码,许多朋友进行了回复,原文地址:http://www.cnblogs.com/loning/archive/2008/06/12/1218381.html
有些朋友说看不懂,也许扩展的确无从下手,没有任何文档,也没多少注释...昨天晚上正好有时间,匆匆写了一个MSN的数据源,使用Dotmsn.

首先,创建一个类库的项目.Loning.Joymsg.DotmsnDataSource,
然后引用项目Loning.Joymsg.Interface.删除程序自动创建的class1.cs,建立DotmsnDataSource.cs.
由于该类为一数据源,因此继承接口IDataSource.
因为整个解决方案我都是用的log4net作日志,引用了Log4net.dll.
关于Dotmsn的东西就不详细说了,网上有许多的例子.

下面具体说一下接口IDataSource.

using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  Loning.Joymsg.Interface
{
    
public interface IDataSource
    
{
        
/**//// <summary>
        
/// 发送消息
        
/// </summary>
        
/// <param name="requester">接受者</param>
        
/// <param name="message">消息内容</param>

        void SendMessage(object requester, string message);
        
/**//// <summary>
        
/// 数据源开始工作
        
/// </summary>

        void Work();
        
/**//// <summary>
        
/// 数据源停止工作
        
/// </summary>

        void Stop();
        
/**//// <summary>
        
/// 消息接收时该事件被触发
        
/// </summary>

        event EventHandler<MessageEventArgs> MessageReceived;
        
/**//// <summary>
        
/// 用户状态改变时该事件被触发
        
/// </summary>

        event EventHandler<FriendStatusChangedEventArgs> FriendStatusChanged;
    }

}

下面是MessageEventArgs的代码

using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  Loning.Joymsg.Interface
{
    
public class MessageEventArgs:EventArgs
    
{
        
/**//// <summary>
        
/// 请求者信息
        
/// </summary>

        public object Requester getprivate set; }
        
/**//// <summary>
        
/// 请求者发送的消息
        
/// </summary>

        public string Message getprivate set; }
        
/**//// <summary>
        
/// 
        
/// </summary>
        
/// <param name="requester">请求者信息</param>
        
/// <param name="message">请求者发送的消息</param>

        public MessageEventArgs(object requester,string message)
        
{
            Requester 
= requester;
            Message 
= message;
        }

    }

}



在DotmsnDataSource中,Work()方法主要实现MSN的登录,而Stop()就是MSN的注销.这些都很容易理解.

我们先抛开好友状态改变的事件.(因为我在实现这个事件的时候遇到点问题,现在也没有解决)

机器人一般是受到消息后进行回复.Dotmsn与LumaQQ.net有所不同,Dotmsn为每一个对话建立了一个Conversation.而普通的聊天(PC上的MSN对MSN),接受消息需要订阅Conversation.Switchboard.TextMessageReceived这个事件,回复时的代码如下:

void  Switchboard_TextMessageReceived( object  sender, TextMessageEventArgs e)
        
{
            log.DebugFormat(
"收到{0}的消息:{1}", e.Sender.Name, e.Message.Text);
            SBMessageHandler handler 
= (SBMessageHandler)sender;
            handler.SendTextMessage(
new TextMessage("something"));
        }

因为MessageEventArgs中定义的Requester只是单纯的传递给Processor,然后再由Processor返回给DataSource,因此定义为Object的Requester属性可以传入任意的对象.于是在这个数据源中,干脆直接传入SBMessageHandler这个对象,然后在SendMessage中转型后直接调用其SendTextMessage方法就可以了.

具体代码实现如下:

public   void  SendMessage( object  requester,  string  message)
        
{
            SBMessageHandler handler 
= (SBMessageHandler)requester;
            SendMessage(handler, message);
        }

private   void  SendMessage(SBMessageHandler handler,  string  message)
        
{
            
            
string[] s = message.Split(new string[]{"\r\n"},StringSplitOptions.None);
            StringBuilder sb 
= new StringBuilder();
            
int i=0;
            
while (i<=s.Length-1)
            
{
                
while (sb.Length < 400 && i <= s.Length - 1)
                
{
                    sb.AppendLine(s[i
++]);
                }

                handler.SendTextMessage(
new TextMessage(sb.ToString()));
                sb.Remove(
0, sb.Length);
            }

            
if(sb.Length>0)
                handler.SendTextMessage(
new TextMessage(sb.ToString()));
        }

void  Switchboard_TextMessageReceived( object  sender, TextMessageEventArgs e)
        
{
            log.DebugFormat(
"收到{0}的消息:{1}", e.Sender.Name, e.Message.Text);
            OnMessageReceived(
new MessageEventArgs(sender, e.Message.Text));
        }
private void SendMessage(SBMessageHandler handler, string message)

这个方法是为了将Message分条发送出去,因为MSN貌似不支持长消息.

整个流程很简单,就是Dotmsn收到消息触发了事件,然后再由DotmsnDataSource触发它的MessageReceived事件,ProcessorManager订阅了这个事件,接受到把具体信息传给特定的Processor,Processor处理完毕后返回信息,ProcessorManager再将处理后的信息返回给Processor(没学过UML...只会看不怎么会画...)然后我们的机器人就说话了:)

然而我没有实现好友状态改变的事件,因为我订阅了Dotmsn的messenger.Nameserver.ContactStatusChanged += new ContactStatusChangedEventHandler(Nameserver_ContactStatusChanged);事件,但是没触发过,无论我怎么改变状态.知道的朋友请告诉我一下问题出在哪里.

该项目的源码
/Files/loning/Loning.Joymsg.DotmsnDataSource.rar

使用的时候请把生成的DLL COPY到Test项目的输出目录,然后修改Test项目的配置文件
配置文件示例

<? xml version="1.0" encoding="utf-8"  ?>
< configuration >
  
< configSections >
    
< section  name ="log4net"  type ="log4net.Config.Log4NetConfigurationSectionHandler,log4net"   />
    
< section  name ="Joymsg"  type ="Loning.Joymsg.Configuration.JoymsgSection,Loning.Joymsg"   />
    
< section  name ="RssProcessor"  type ="Loning.Joymsg.RssProcessor.Configuration.RssProcessorSectionHandler, Loning.Joymsg.RssProcessor"   />
  
</ configSections >
  
< log4net >
    
< root >
      
< level  value ="ALL"   />
      
< appender-ref  ref ="rollingFile"   />
      
< appender-ref  ref ="coloredConsoleAppender"   />
    
</ root >
    
< appender   name ="rollingFile"  type ="log4net.Appender.RollingFileAppender,log4net"   >
      
< lockingModel  type ="log4net.Appender.FileAppender+MinimalLock"   />
      
< param  name ="File"  value ="log"   />
      
< param  name ="AppendToFile"  value ="true"   />
      
< param  name ="RollingStyle"  value ="Date"   />
      
< param  name ="DatePattern"  value ="yyyy.MM.dd"   />
      
< param  name ="StaticLogFileName"  value ="false"   />
      
< layout  type ="log4net.Layout.PatternLayout,log4net" >
        
< param  name ="ConversionPattern"  value ="%d [%t] %-5p %c - %m%n"   />
        
< param  name ="Header"  value =" ----------------------header-------------------------- "   />
        
< param  name ="Footer"  value =" ----------------------footer-------------------------- "   />
      
</ layout >
    
</ appender >
    
< appender  name ="coloredConsoleAppender"  type ="log4net.Appender.ColoredConsoleAppender" >
      
< mapping >
        
< level  value ="ERROR"   />
        
< foreColor  value ="White"   />
        
< backColor  value ="Red, HighIntensity"   />
      
</ mapping >
      
< mapping >
        
< level  value ="DEBUG"   />
        
< backColor  value ="Green"   />
      
</ mapping >
      
< mapping >
        
< level  value ="INFO"   />
        
< foreColor  value ="White"   />

      
</ mapping >
      
< layout  type ="log4net.Layout.PatternLayout" >
        
< conversionPattern  value ="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"   />
      
</ layout >
    
</ appender >
  
</ log4net >
  
< Joymsg  processMessage ="收到消息{0}处理中,请稍候,您可以使用&quot;?&quot;查询命令" >
    
< DataSources >
      
< add  name ="lumaQQ"  type ="Loning.Joymsg.LumaQQDataSource.LumaQQDataSource, Loning.Joymsg.LumaQQDataSource, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"   />
      
< add  name ="dotmsn"  type ="Loning.Joymsg.DotmsnDataSource.DotmsnDataSource, Loning.Joymsg.DotmsnDataSource, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"   />
    
</ DataSources >
    
< Processors >
      
< add  name ="default"  type ="Loning.Joymsg.DefaultProcessor.DefaultProcessor, Loning.Joymsg.DefaultProcessor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"   />
      
< add  name ="online"  type ="Loning.Joymsg.DefaultProcessor.DefaultProcessor, Loning.Joymsg.DefaultProcessor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"   />
      
< add  name ="fy"  type ="Loning.Joymsg.TranslationProcessor.TranslationProcessor, Loning.Joymsg.TranslationProcessor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"   />
      
< add  name ="rss"  type ="Loning.Joymsg.RssProcessor.RssProcessor, Loning.Joymsg.RssProcessor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"   />
    
</ Processors >
  
</ Joymsg >
  
< RssProcessor >
    
< RssChannels >
      
< add  name ="cnblogs"  url ="http://www.cnblogs.com/rss"   />
      
< add  name ="news"  url ="http://news.cnblogs.com/rss"   />
      
< add  name ="cnbeta"  url ="http://www.cnbeta.com/backend.php"   />
      
< add  name ="kc"  url ="http://www.adjie.com/club/rss.php?fid=38&amp;auth=0"   />
      
< add  name ="163"  url ="http://news.163.com/special/00011K6L/rss_newstop.xml"   />
      
< add  name ="sina"  url ="http://rss.sina.com.cn/news/marquee/ddt.xml"   />
      
< add  name ="nba"  url ="http://rss.sina.com.cn/sports/basketball/nba.xml"   />
      
< add  name ="game"  url ="http://rss.sina.com.cn/games/eqxw.xml"   />
    
</ RssChannels >
  
</ RssProcessor >
  
< appSettings >
    
< add  key ="luma:qq"  value ="971125573"   />
    
< add  key ="luma:password"  value =""   />
    
< add  key ="luma:clusterReply"  value ="true"   />
    
< add  key ="luma:addFriendAuthMessage"  value ="我是QQ机器人,请让我加你为好友"   />
    
< add  key ="dotmsn:account"  value ="loningrobot@hotmail.com" />
    
< add  key ="dotmsn:password"  value ="" />
  
</ appSettings >
</ configuration >



 

转载于:https://www.cnblogs.com/loning/archive/2008/06/16/1223077.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值