MSN机器人梦工厂

前几日看到网友“瞄瞄”的一个关于msn机器人的blog文章。然后在google上搜索了一下,原来,现在流行MSN机器人了!

由于MSN Messenger公开了它的通讯协议,使得很多人加入到编写自己的机器人的行列。msn协议全文共有20页,相比smtp协议来说是少得多了。但对于大多数开发者来说,根据原始协议来写机器人程序仍然是一件困难的事(更何况协议内容是英文的)。

也是在google上,我发现在Java领域,比较流行的机器人开发工具是一个韩国人写的一个jMSN开发包。它将复杂的协议封装成简单易用的Java API供使用者调用。(下载地址:http://sourceforge.net/projects/jmsn)

话虽这么说,使用起来还是有点阻碍的。整个jMSN开发包的文档全部是韩文写成,对于我们这些连英文都很吃力的人来说,这简直就是天书!

不过不要紧,欢迎大家进入机器人梦工厂,同我一起来探索MSN机器人的制造过程。


现在我们就开始实现自制MSN机器人梦想。

我们先不要去研究通篇韩文的开发文档。先跟笔者一起来研究一个有趣的机器人,看看它是怎么工作的。然后再一步步深入研究机器人的工作原理。

这是一个有趣的机器人,你对它说什么,它就应什么。我把它叫做应声虫机器人。来看看它的结构:

import java.util.Properties;

import rath.msnm.MSNMessenger;
import rath.msnm.SwitchboardSession;
import rath.msnm.UserStatus;
import rath.msnm.entity.MsnFriend;
import rath.msnm.event.MsnListener;
import rath.msnm.ftp.VolatileDownloader;
import rath.msnm.ftp.VolatileTransferServer;
import rath.msnm.msg.MimeMessage;

/**
* MSN应声虫机器人。
* @author Turbo Chen
* @create 2004-7-29
*/
public class YesmanRobot
{
public static void main(String[] args)
{
MSNMessenger msn = new MSNMessenger("yourname@hotmail.com", "xxxxxxxx");
msn.setInitialStatus(UserStatus.ONLINE);
msn.addMsnListener(new YesmanRobotAdapter(msn));
msn.login();
}


}


class YesmanRobotAdapter implements MsnListener
{

MSNMessenger msn;

public YesmanRobotAdapter(MSNMessenger msn)
{
this.msn = msn;
}

/**
* 收到消息事件。当收到消息时,会自动调用此方法。
*/
public void instantMessageReceived(SwitchboardSession ss, MsnFriend friend,
MimeMessage mmsg)
{
try
{
//发送相同的回复信息给发送者
MimeMessage newMsg = new MimeMessage(
"我是MSN应声虫,你说啥我应啥:" + mmsg.getMessage());
newMsg.setKind(MimeMessage.KIND_MESSAGE);
System.out.println(newMsg.getMessage());
msn.sendMessage(friend.getLoginName(), newMsg);
} catch (Exception e)
{
e.printStackTrace();
}
}

....
}

其中YesmanRobot是机器人的主类,为了让机器人工作,要先让它登入到MSN才行,相关代码如下:

MSNMessenger msn = new MSNMessenger("yourname@hotmail.com", "xxxxxxxx");
msn.setInitialStatus(UserStatus.ONLINE);
msn.addMsnListener(new YesmanRobotAdapter(msn));
msn.login();

在这里创建了一个MSNMessenger对象,传入登入帐号和密码,使用setInitialStatus方法设置它登入的的状态为'在线',最后是调用login方法登入。

为了使机器人可以达到“应声虫”的功能,在登入之前,我们为它添加了一个监听器。这个监听器是MSNListener的一个实现类。在这里我们实现了一个YesmanRobotAdapter类,它里面只实现一个instantMessageReceived方法,当有消息送给机器人时,会触发此方法,在这个方法里,我们的机器人将对方送过来的消息又送回给了对方。这样就实现的应声虫的功能。

在实际的完整例子中,你会发现MSNListener有多达28个接口,也就是说它除了可以监听收到消息的事件,还提供了许多其它的事件供我们使用。在以后的文章中,我们会慢慢的接触到这些事件。

通过这个应声虫机器人,我们知道,实现自己功能的机器人一点都不难。只需要在instantMessageReceived方法中处理收到的消息并回应,就变成你自己的机器人了。在后面的内容中,我们会更深入机器人内部,看看它的工作原理。


废话少说。接上回。

由上回的一个应声虫机器人的例子,我们初步了解到jmsn开发包的基本用法,我先画一个它的工作原理图给大家:

jmsn原理图

MSNMessenger为主程序。它包含一个NotificationProcessor,这个一个通讯事件的处理器,本质上它是一个独立运行的线程。MSNMessenger提供许多命名友好的方法来向其它联系人(透过服务器)发送通讯命令。发送通讯命令都是通过NotificationProcessor处理器在后台(独立线程)处理的。

所有的通讯命令都封装在命名友好的方法中发送,这样你就勿需了解MSNMessenger的底层通讯协议。MSNMessenger提供了许多实用的方法来调用。比如有登入和注销(login, logout),添加或删除好友(addFriend, removeFriend),建立和删除群组(addGroup, removeGroup),邀请友人聊天(doCall),或者邀请某人加入到现有的聊天中等等。有了这些现成的方法,你可以让你的机器人变成非常强大,当然,也完全可以用它做一个替代Microsoft Messenger的聊天工具。

命令通过处理器发送出去之后,并不是马上返回。它是在后台由处理器负责运行的。也就是说,你调用了登入命令之后,如果想马上添加某人为好友,这时程序会报错。登入过程可能是一个慢长的过程,它要与服务器通讯,要等待服务器返回回应信息。而处理器在后台做这些事情,做完后,它会通过你注册在MSNMessenger类中的MSNListener监听器通知你。

所以不要试者一连串的执行MSNMessenger中提供某些方法(主要是指前面提到的那些类似方法),你应该在自己的监听器中等待事件完成后的通知你后再执行相应命令。

MSNListener是一个接口,提供了多达28种事件通知方法。包括登入完成,好友上线或离线,开始会话或结束会话,收到新消息,有谁添加自己为好友等事件。

这次的说教就到这。最后我们来改进一下上次的应声虫程序,让它可以在某人上线后主动发一个消息给他打招呼(不然谁知道你是个应声虫:D)。

代码别的地方都一样,只是在YesmanRobotAdapter新实现了两个方法:

/**
* 好友上线时开始与其对话。
*/
public void userOnline(MsnFriend friend)
{
try
{
System.out.println("开始邀请"+friend.getLoginName()+"会话");
msn.doCall(friend.getLoginName());

} catch (IOException e)
{
// TODO 处理异常
e.printStackTrace();
}
}

/**
* 会话开始。
*/
public void switchboardSessionStarted( SwitchboardSession ss )
{
try
{

if ( ss==null ) return;

String toFriend = ss.getMsnFriend().getLoginName();

if ( msn.findSwitchboardSession(toFriend)!=null )
{
MimeMessage msg = new MimeMessage("你好,这是MSN应声虫机器人自动与你通话。欢迎提问");
msg.setKind(MimeMessage.KIND_MESSAGE);
boolean success = msn.sendMessage(toFriend, msg);
if ( success )
System.out.println("打完招呼.");
}


} catch (IOException ex)
{
// TODO 处理异常
ex.printStackTrace();
}
}

在这里,首先在用户上线的事件通知userOnline里调用了doCall方法。doCall方法是开始与友人的通讯。这时候还不能马上向其发消息,要等到会议开始之后,所以又实现了一个switchboardSessionStarted。当会话开始后,我们的机器人就可以在你上线的时候主动发出问题了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值