现在各类即时通信软件琳琅满目,相信接触过INTERNET的人都会使用过其中的一部分。在中国就目前用户量而言,腾讯公司的QQ、微软公司的MSN Messenger以及网易公司的POPO排名在前三位。不过令人比较遗憾的是,腾讯公司和网易公司对于QQ以及POPO使用的通信协议并没有对外界公开,正是由于这样的技术壁垒,使得一些即时通信的开发者很难在这些用户群中开辟新的客户服务渠道。 

不过值得庆幸的是,由微软公司开发的MSN即时通信软件,其客户端与WINDOWS系统的紧密整合,加之其运行稳定、简单易用以及全世界通用性强等特点。简体中文版一经推出,用户数量即以几何数量的增加。更令大家欢呼雀跃的是微软公司还提供的MSN的开发API并在其网站上向全世界公布了MSN的通信协议。这令众多开发者为MSN拓展功能和对客户进行更个性化的服务成为可能,例如著名的MSN PLUS就是一款通过MSN API开发的MSN功能扩展插件,目前已经为众多MSN使用者所接收。 

同时,通过MSN的通信协议,网络上更出现了为数众多的使用MSN通信协议的MSN机器人。他们通过接收用户的消息并进行自动化的处理,使MSN的用户能够享受到各类公共信息的服务。 

技术介绍 

由于MSN通信协议是基于TCP/IP的ASCII文本协议,因此通过WINDOWS的SOCKET与微软架设在全球的MSN服务器按照既定的协议进行通信,就可以与全球的MSN用户进行即时的消息和文件的传输(具体的MSN协议可以通过该网页获得http://www.hypothetic.org/docs/msn/index.php)。不过MSN的协议颇为复杂,而且通信命令全部都是英语的缩写,对于初识该协议的开发者来说,熟悉和实现协议费时又费力。 
[网络动力] upwork.cn

现在网络上有一些实现了MSN P8协议的开发包可以供开发者使用,这样就可以使大家把精力更专注于逻辑的实现。 

目前比较流行的开发包有两种: 

1.jMSN是封装了MSN Messenger开放的通讯协议的JAVA API,通过这个API开发者完全可以使用JAVA语言模拟出MSN Messenger软件,API的作者也提供一个用JAVA语言编写的在某方面功能甚至比MSN Messenger还强大的MSN 客户端软件。由于采用了跨平台的JAVA语言开发,因此该软件也可同时运行于其他操作系统,目前已经经过测试的有各种Linux系统以及Mac OS上,当然还有视窗操作系统。jMSN是一个韩国人开发的开放源码的API,可以从http://sourceforge.net/projects/jmsn/站点上下载,该项目的首页基本上以韩文为主,包括它的API文档的说明都是韩文。 

2.dotMSN是由一位丹麦的高手开发的基于.NET的开发包,使用的使MSN P8协议,虽然它没有支持到目前刚刚推出的MSN P10。但是,其开发包的功能之强大,是我使用过的MSN开发包中最好的。尤其值得称道的是,作者对于dotMSN提供了非常详尽的文档支持和示例代码(http:///b.geertsema/dotMSN/example/Example.zip)。利用该开发包,你可以轻松地实现自己的MSN机器人。 
[网络动力]

现在,我就来带领大家建立自己的MSN机器人了。 

技术准备 

在使用dotMSN之前,我先给大家介绍一下.NET框架的大致情况以及集成开发环境,这样便于大家在开发时更方便、快捷。 

.NET框架 

.NET 框架是 Windows Server System 构建,部署与运行 Web 服务与应用程序的编程模型。该框架托管了大部分深层结构,让开发人员专注于撰写应用程序的业务逻辑代码。.NET 框架的基本构成如下: 

l 公共语言运行库(CLR) 

l .NET Framework类 

l ASP.NET 

l Web Service 

l .NET远程处理 

l Windows窗体类 

其中CLR和.NET框架是所有基于.NET程序的基础。 

CLR可以是各类不同的应用程序(ASP.NET程序、移动程序、WINDOWS窗体程序)等都基于同样的运行库中。在部署和产品发布中可以轻松地屏蔽掉在VS 6.0时代被大家成为“DLL噩梦”的DLL重复版本问题。 

.NET 框架包括了大量类,接口,以及值类型,使开发过程得以加速和优化,同时提供了系统功能的访问途径。为了实现跨语言操作性,.NET 框架类型遵从公共语言规范 (CLS) ,因此可以使用任何有编译器支持的语言。这就允许企业的 IT 部门在保留现有开发人员基础上得以拓展,迅速开始 .NET 应用程序的开发,或利用完全的互操作性对现有应用程序用 .NET 特性加以改进。 

其他的基本构成大都与不同类型的应用有关。 

ASP.NET 是一个革命性的编程框架,使快速开发强大的 Web 应用程序和服务成为可行。它提供了最方便、最灵活的途径来构建,部署和运行 Web 应用程序,面向任何浏览器或设备。 

XML Web 服务是一个包装成单个实体的系列函数集,并发布出来为其他应用程序提供数据和服务。应用程序通过行业标准的万维网协议与数据格式,如 HTTP,XML,以及简单对象访问协议 (Simple Object Access Protocol, SOAP) 来访问 Web 服务,且不需要关心 Web 服务的具体实现方法。Web 服务是建立开放分布式系统的基石。 

通信是跨网络或跨应用程序域对象的关键因素,这些对象又被称作远程对象。.NET 远程处理提供了一种强力高效的机制,允许对象之间跨越应用程序域实现交互。 

存在于 .NET 应用程序及应用程序域之间的通信,通过负责在远程对象之间传送消息的通道而产生。一条消息被通道传送前,会首先被格式化程序格式化(编码或解码)。.NET 框架支持 HTTP 和 传输控制协议 (TCP) 通道,以及 SOAP 和二进制的格式化程序。HTTP 通道使用 SOAP 格式化程序来传送消息,而 TCP 通道使用二进制格式化程序。这两种通道都可以自定义使用其他的格式化程序。第三方提供的通道同样是可行的。HTTP 通道使用 SOAP 格式化程序来传送消息,而 TCP 通道使用二进制格式化程序。这两种通道都可以自定义使用其他的格式化程序。第三方提供的通道同样是可行的。 

Windows 窗体拓展了传统的完全桌面化的 Windows 应用程序,同时,Visual Studio 带来的开发体验将我们带入托管代码与公共语言运行库的世界。 

集成开发环境 
要创建在 .NET 公共语言运行库和 .NET 框架类中运行托管代码的 .NET 应用程序,Visual Studio .NET 是首选的集成开发环境 (IDE)。它延续了 Visual Studio 的传统,允许开发人员编译以前的非托管 C++ 或 C# 应用程序。 
Visual Studio .NET 让快速开发应用程序 (RAD) 通过高效开发工具得以实现。一个紧密集成且统一的可视环境简化了开发 Web 应用程序的过程,降低了学习曲线。共享的超文本标记语言 (HTML),XML,以及样式表编辑器令使用任何 Visual Studio 语言开发 Web 应用程序变得十分容易,包括使用新的 C# 编程语言。 

Visual Studio .NET 允许开发人员快速构建新的托管代码的应用程序,面向 .NET 框架丰富的功能与类库。Visual Studio .NET 同样允许开发人员采用优化过的编译器出品传统的非托管代码的 C++ 应用程序,如 Microsoft Word 或 Microsoft Excel。 

程序开发 

下面大家就和我一起开始制作自己的机器人吧 

引入dotMSN开发包 
首先我们要先建立一个解决方案,由于.NET框架CLS(通用语言规范)可以支持多种不同的开发语言,因此你在建立解决方案的时候可以使用目前.NET支持的VB.NET、C#、J#、C++等语言。 

在解决方案建立后,第一步需要做的就是将dotMSN开发包引用到解决方案中来,以便我们可以在今后的开发过程中使用。 

可以看到在引用的文件列表中已经加入了DotMSN的开发包,下面在我们通过IDE设计好机器人程序的用户界面后就可以开始使用DotMSN与MSN服务器通信了。 

在DotMSN中有Messenger类,它就是你编程的全部,所以你在程序的开始就要声明该类的一个对象并同时申请内存及初始化: 

private DotMSN.Messenger messenger = new Messenger(); 

在你输入的MSN机器人的邮件地址、认证密码及显示的名称后,首先要做的就是登录到MSN服务器上,我这里自己编写了一个StartMSN函数来包含登录动作,当然该函数中不止包含登录,对于登录以后MSN的一些消息事件也做了重载的声明: 

//启动MSN程序 
private void StartMSN() 
{ 
try 
{ 
//确认输入的PASSPORT帐号不是默认的设置,否则报错误! 
if(txtMail.Text == "yourmail@hotmail.com") 
MessageBox.Show(this, "键入你的PASSPORT以登录MSN服务器!"); 
else 
{ 
//事件重载代码段 
//重载上线函数 
messenger.ContactOnline += new Messenger.ContactOnlineHandler(ContactOnline); 
//重载下线函数 
messenger.ContactOffline += new Messenger.ContactOfflineHandler(ContactOffline); 
 upwork.cn//重载联系人加入函数 
messenger.ContactAdded += new Messenger.ContactAddedHandler(ContactAdded); 
//重载会话创建函数 
messenger.ConversationCreated += new Messenger.ConversationCreatedHandler(ConversationCreated); 
//重载同步处理函数 
messenger.SynchronizationCompleted += new Messenger.SynchronizationCompletedHandler(OnSynchronizationCompleted); 
messenger.Connect(txtMail.Text, txtPass.Text); 
Log(this.txtMail.Text + "登录成功!"); 
messenger.SynchronizeList(); 
} 
} 
catch(MSNException e) 
{ 
MessageBox.Show(this, "连接失败:" + e.ToString()); 
Log("连接失败:" + e.ToString()); 
} 
}

其中messenger的Connect方法是登录MSN服务器的主要方法,在登录之前我们需要对于MSN的一些消息事件做重载处理,以便将来这些事件触发时可以调用我们自己编写的逻辑处理代码。 

在登录到MSN服务器成功后,马上需要调用的方法就是SynchronizeList(),即与服务器同步联系人列表,列表分为以下4种: 
upwork.cn

1)ForwardList:所有有效联系人列表,可以互相发送消息。 

2)ReverseList:所有你在对方联系人列表中的联系人列表。 

3)BlockedList:所有你阻止的联系人列表。 

4)AllowedList:所有能够看到你状态的联系人列表。 

通过对于上述4种列表的操作,可以让机器人了解所有联系人的相关状态并实施相应的操作。 

在同步联系人列表结束后,需要设置messenger的状态,MSNStatus是状态的枚举量,使用SetStatus方法来进行设置,状态包括:在线、离线、离开、马上回来、外出就餐等,通过对状态变量的设置可以让联系人看到机器人的不同在线情况。同时通过messenger.Owner.Name的设置可以让机器人在联系人端显示你需要的名称。 

接下来比较主要的工作就是对于MSN各类事件的重载处理了,我这里举两个事件处理的例子,其他的事件可以从dotMSN的帮助文件中查阅。机器人的各类逻辑就是通过对于这些事件的重载来实现的。 

//会话创建时间处理程序 
private void ConversationCreated(Messenger sender, ConversationEventArgs e) 
{ 
//记录会话创建日志 
txtLog.AppendText("会话创建成功!\r\n"); upwork.cn[网络动力] 
//当联系人加入对话时处理函数 
e.Conversation.ContactJoin += new Conversation.ContactJoinHandler(ContactJoined); //连接建立时处理函数 
e.Conversation.ConnectionEstablished += new Conversation.ConnectionEstablishedHandler(ConnectionEstablished); 
//联系人输入消息时处理函数 
e.Conversation.UserTyping += new Conversation.UserTypingHandler(ContactTyping); 
//处理消息收到消息 
e.Conversation.MessageReceived += new Conversation.MessageReceivedHandler(MessageReceived); 
//接收文件传输时处理函数 
e.Conversation.FileTransferHandler.InvitationReceived +=new DotMSN.FileTransferHandler.FileTransferInvitationHandler(FileTransferHandler_FileTransferInvitation); 
}

第一个需要处理的就是会话创建事件,也就是机器人与联系人开始会话的情况,代码中重载了5个相关的事件,从代码中已经能够猜想这些事件的大致用途了。会话创建事件本身的重载工作是在StartMSN()中声明的。下面就是这些事件的重载代码: 

//联系人输入消息时处理函数 
private void ContactTyping(Conversation sender, ContactEventArgs e) 
{ 
txtLog.AppendText(e.Contact.Name + "正在输入消息...\r\n"); 
Log(e.Contact.Name + "正在输入消息..."); 
} 
//联系人加入对话处理函数 
private void ContactJoined(Conversation sender, ContactEventArgs e) 
{ 
//联系人加入对话,记录联系人姓名到日志中 
txtLog.AppendText(e.Contact.Name + "加入对话!\r\n"); 
Log(e.Contact.Name + "加入对话!"); 
//输入欢迎词 
sender.SendMessage("你好啊!我是" + messenger.Owner.Name); 
sender.SendMessage("发送短信请使用以下命令:手机号码#要发送的内容"); 
//sender.SendMessage("如果需要帮助文件,请键入get_help_file"); 
} 
//连接建立处理函数 
private void ConnectionEstablished(Conversation sender, EventArgs e) 
 [网络动力]{ 
txtLog.AppendText("连接完成!\r\n"); 
} 
//收到联系人消息时处理函数 
private void MessageReceived(Conversation sender, MessageEventArgs e) 
{ 
string msg_rcv = e.Message.Text; 
msg_rcv = e.Message.Text.Replace("\0", ""); 
txtLog.AppendText( + "说:" + msg_rcv + "\r\n"); 
Log( + "说:" + msg_rcv); 
string msg_dnt = MessageHandle(msg_rcv, , e.Sender.Mail); 
sender.SendMessage(msg_dnt); 
Log("机器人发送消息:" + msg_dnt); 
} 
//文件接收动作处理函数 
private void FileTransferHandler_FileTransferInvitation(FileTransferHandler sender, FileTransferInvitationEventArgs e) 
{ 
//接收动作为真 
e.Accept = true; 
//收到的文件保存在D:\MSN_BOT_FILES下 
string tmpfile = "D:\\FileOfBot\\" + sender.Conversation.Messenger.Owner.Name + "@" + e.FileTransfer.FileName; 
 [网络动力] upwork.cn e.FileTransfer.ReceiveStream = new FileStream(tmpfile, FileMode.Create, FileAccess.ReadWrite); 
txtLog.AppendText("接收文件并保存到:" + tmpfile + "\r\n"); 
}

在这些事件当中,MessageReceived事件比较重要,它表示当机器人接收到用户发送的文字消息时所进行的处理逻辑,这里也就是你可以自由发挥的地方了!我这里编写了独立的MessageHandle函数来对于所有收到的消息进行处理。在该处理函数中,所有机器人的智能情况和相关的业务功能都可以根据你自己对于机器人的定位来实现。 

我这里的机器人所做的就是将用户发送的消息命令解码并根据用户输入的目标移动中断发送移动短信。当然这里是需要后端有短信网关或者是相关的短信发送设备的支持。你看,你轻松地就拥有了自己的短信服务机器人了。 

在后端有相关数据库的支持下,机器人同样可以根据用户的输入来查询数据库的相关信息并返回给用户。 

在拓展用户、客户服务、产品推介等方面又多了一条网络的途径! 

结尾 
好了,关于MSN机器人方面就先写到这里吧。目前我自己也在更深入地钻研MSN的协议,希望能够与具有相同兴趣的朋友一起交流。期待着你们的来信。