发了几篇与DotMSN有关的博客后,有些朋友也在问我关于开发MSN机器人的一些问题。我也没有用过DotMSN 1.0,不知道他是什么样的,那我就用DotMSN 2.0简单介绍一下如何使用DotMSN来开发MSN机器人。在DotMSN的源码中,已经有完整的例子了,只是对一些事件没有做更详细的介绍和使用说明。
要登录MSN,要先创建一个Messenger类型的对象,并且设置好一些环境参数:
1: messenger.Credentials.ClientID = "msmsgs@msnmsgr.com";
2: messenger.Credentials.ClientCode = "Q1P7W2E4J9R8U3S5";
3: messenger.Credentials.Account = parameters["Account"];
4: messenger.Credentials.Password = parameters["Password"];
5: messenger.Connect();
正常情况下,这几句代码后,MSN就可以正常登录了,如果你使用的是代理上网,那么你可以还需要如下的设置:
1: if (!string.IsNullOrEmpty(parameters["ProxyHost"]))
2: {
3: messenger.ConnectivitySettings.ProxyHost = parameters["ProxyHost"];
4: messenger.ConnectivitySettings.ProxyPort = int.Parse(parameters["ProxyPort"]);
5: messenger.ConnectivitySettings.ProxyType = (ProxyType)Enum.Parse(typeof(ProxyType), parameters["ProxyType"]);
6: }
指定所使用的代理服务器和端口即可登录。
但是单单可以登录还是不够的,还需要对MSN的状态进行监控。这些就必须要通过DotMSN提供的事件来达到目的了,而根据事件的分类的不同,这些事件被分别定义在不同的类型里面:
在Messenger类中定义了两个事件,分别为ConversationCreated和TransferInvitationReceived,这两个事件分别是在会话创建时和文件转输请求时触发的。TransferInvitationReceived用于处理文件传输的请求,由于需要比较复杂的处理,并且做为机器人本身并不太需要这个功能,所以这里不做详细介绍。
ConversationCreated事件
它的事件参数类型为ConversationCreatedEventArgs,它定义了一个Conversation成员对象,用于描述当前会话的上下文信息。在DotMSN中,每个会话创建实际上都创建了一个Conversation类型对象,它被维护在Messenger一个叫conversations的私有成员列表里面,当会话在一段时间内没有被激活时,DotMSN将会自动释放一些不需要的Conversation对象。所以我们根本就不要关心,如何去维护过期的会话。
在Conversation对象中也定义了一些事件,这些事件是与当前会话有关的。比如,有联系人加入和离开时,收到信息时,会话关闭时,用户在打字时等等这些状态事件,这些事件是定义在Conversation的Switchboard属性中(SBMessageHandler类型),它们分别为,:
1: public event SBChangedEventHandler AllContactsLeft;
2: public event ContactChangedEventHandler ContactJoined;
3: public event ContactChangedEventHandler ContactLeft;
4: public event EmoticonDefinitionReceivedEventHandler EmoticonDefinitionReceived;
5: public event HandlerExceptionEventHandler ExceptionOccurred;
6: public event ErrorReceivedEventHandler ServerErrorReceived;
7: public event SBChangedEventHandler SessionClosed;
8: public event SBChangedEventHandler SessionEstablished;
9: public event TextMessageReceivedEventHandler TextMessageReceived;
10: public event UserTypingEventHandler UserTyping;
Nameserver属性
1: public event HandlerExceptionEventHandler AuthenticationError;
2: public event ListMutatedAddedEventHandler ContactAdded;
3: public event ContactGroupChangedEventHandler ContactGroupAdded;
4: public event ContactGroupChangedEventHandler ContactGroupChanged;
5: public event ContactGroupChangedEventHandler ContactGroupRemoved;
6: public event ContactChangedEventHandler ContactOffline;
7: public event ContactChangedEventHandler ContactOnline;
8: public event ListMutatedAddedEventHandler ContactRemoved;
9: public event ContactStatusChangedEventHandler ContactStatusChanged;
10: public event HandlerExceptionEventHandler ExceptionOccurred;
11: public event MailChangedEventHandler MailboxChanged;
12: public event MailboxStatusEventHandler MailboxStatusReceived;
13: public event NewMailEventHandler NewMailReceived;
14: public event PingAnswerEventHandler PingAnswer;
15: public event ContactChangedEventHandler ReverseAdded;
16: public event ContactChangedEventHandler ReverseRemoved;
17: public event SBCreatedEventHandler SBCreated;
18: public event ErrorReceivedEventHandler ServerErrorReceived;
19: public event EventHandler SignedIn;
20: public event SignedOffEventHandler SignedOff;
21: public event EventHandler SynchronizationCompleted;
这些事件,监听了各种网络事件,和MSN自身的事件通知,比如ReverseAdded是当有添加自己为好友请求发生时触发的。
除了这些事件外,还有一些关于如何发送信息,如何向好友发送当前处理打字状态,如何保持连接等这些主题,都会在下面的例子中有所描述。或者你去查阅一下DotMSN的接口也可以很容易的找到答案。
示例:
1: using System;
2: using System.Collections.Generic;
3: using System.Text;
4: using System.Timers;
5:
6: using XihSolutions.DotMSN;
7:
8: namespace MSNRobot
9: {
10: class Program
11: {
12: static Messenger messenger = new Messenger();
13: static Timer timer;
14:
15: static void Main(string[] args)
16: {
17: // by default this example will emulate the official microsoft windows messenger client
18: messenger.Credentials.ClientID = "msmsgs@msnmsgr.com";
19: messenger.Credentials.ClientCode = "Q1P7W2E4J9R8U3S5";
20: messenger.Nameserver.PingAnswer += new PingAnswerEventHandler(Nameserver_PingAnswer);
21: messenger.NameserverProcessor.ConnectionEstablished += new EventHandler(NameserverProcessor_ConnectionEstablished);
22: messenger.Nameserver.SignedIn += new EventHandler(Nameserver_SignedIn);
23: messenger.Nameserver.SignedOff += new SignedOffEventHandler(Nameserver_SignedOff);
24: messenger.NameserverProcessor.ConnectionException += new XihSolutions.DotMSN.Core.ProcessorExceptionEventHandler(NameserverProcessor_ConnectionException);
25: messenger.Nameserver.ExceptionOccurred += new XihSolutions.DotMSN.Core.HandlerExceptionEventHandler(Nameserver_ExceptionOccurred);
26: messenger.Nameserver.AuthenticationError += new XihSolutions.DotMSN.Core.HandlerExceptionEventHandler(Nameserver_AuthenticationError);
27: messenger.Nameserver.ServerErrorReceived += new XihSolutions.DotMSN.Core.ErrorReceivedEventHandler(Nameserver_ServerErrorReceived);
28: messenger.ConversationCreated += new ConversationCreatedEventHandler(messenger_ConversationCreated);
29: messenger.TransferInvitationReceived += new XihSolutions.DotMSN.DataTransfer.MSNSLPInvitationReceivedEventHandler(messenger_TransferInvitationReceived);
30: messenger.Nameserver.ReverseAdded += new ContactChangedEventHandler(Nameserver_ReverseAdded);
31:
32: //messenger.ConnectivitySettings.ProxyHost = "192.168.7.62";
33: //messenger.ConnectivitySettings.ProxyPort = 1080;
34: //messenger.ConnectivitySettings.ProxyType = ProxyType.Socks5;
35:
36: messenger.Credentials.Account = "";
37: messenger.Credentials.Password = "";
38:
39: timer = new Timer(3000);
40: timer.Enabled = true;
41: timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
42: WL("Connecting to server");
43: try
44: {
45: messenger.Connect();
46: }
47: catch (Exception e)
48: {
49:
50: WL(e.Message);
51: }
52: RL();
53:
54: }
55: static void timer_Elapsed(object sender, ElapsedEventArgs e)
56: {
57: SendPing();
58: }
59: static private void ReConnect()
60: {
61: try
62: {
63: timer.Stop();
64: WL("Disconnecting");
65: messenger.Disconnect();
66: WL("Reconnecting");
67: messenger.Connect();
68: }
69: catch (Exception e)
70: {
71: System.Threading.Thread.Sleep(3000);
72: ReConnect();
73: }
74:
75: }
76:
77: static void Nameserver_ReverseAdded(object sender, ContactEventArgs e)
78: {
79: Console.WriteLine("Nameserver_ReverseAdded");
80: messenger.Nameserver.AddContactToList(e.Contact, MSNLists.AllowedList);
81: e.Contact.OnAllowedList = true;
82: e.Contact.OnForwardList = true;
83: }
84:
85: static void messenger_TransferInvitationReceived(object sender, XihSolutions.DotMSN.DataTransfer.MSNSLPInvitationEventArgs e)
86: {
87: WL("messenger_TransferInvitationReceived");
88: }
89:
90: static void messenger_ConversationCreated(object sender, ConversationCreatedEventArgs e)
91: {
92: e.Conversation.Switchboard.TextMessageReceived += new TextMessageReceivedEventHandler(Switchboard_TextMessageReceived);
93: e.Conversation.Switchboard.ContactJoined += new ContactChangedEventHandler(Switchboard_ContactJoined);
94: e.Conversation.Switchboard.ContactLeft += new ContactChangedEventHandler(Switchboard_ContactLeft);
95: e.Conversation.Switchboard.SessionClosed += new SBChangedEventHandler(Switchboard_SessionClosed);
96: e.Conversation.Switchboard.UserTyping += new UserTypingEventHandler(Switchboard_UserTyping);
97: }
98:
99: static void Switchboard_UserTyping(object sender, ContactEventArgs e)
100: {
101: WL(e.Contact.Name + "is typing");
102: //发送打字状态
103: ((XihSolutions.DotMSN.SBMessageHandler)sender).SendTypingMessage();
104: }
105:
106: static void Switchboard_SessionClosed(object sender, EventArgs e)
107: {
108: WL("session closed");
109: }
110:
111: static void Switchboard_ContactLeft(object sender, ContactEventArgs e)
112: {
113: WL("{0} left", e.Contact.Name);
114: }
115:
116: static void Switchboard_ContactJoined(object sender, ContactEventArgs e)
117: {
118: WL("{0} joined.", e.Contact.Name);
119: }
120:
121: static void Switchboard_TextMessageReceived(object sender, TextMessageEventArgs e)
122: {
123: WL("{0} says : {1}", e.Sender, e.Message);
124: XihSolutions.DotMSN.SBMessageHandler handler = (XihSolutions.DotMSN.SBMessageHandler)sender;
125: handler.SendTextMessage(new TextMessage(string.Format("您好,你跟我说:{0}", e.Message.Text)));
126: }
127:
128: static void Nameserver_ServerErrorReceived(object sender, MSNErrorEventArgs e)
129: {
130: WL("Nameserver_ServerErrorReceived");
131: }
132:
133: static void Nameserver_AuthenticationError(object sender, ExceptionEventArgs e)
134: {
135: WL("Nameserver_AuthenticationError");
136: }
137:
138: static void Nameserver_ExceptionOccurred(object sender, ExceptionEventArgs e)
139: {
140: WL("Nameserver_ExceptionOccurred");
141: }
142:
143: static void NameserverProcessor_ConnectionException(object sender, ExceptionEventArgs e)
144: {
145: WL("NameserverProcessor_ConnectionException");
146: }
147:
148: static void Nameserver_SignedOff(object sender, SignedOffEventArgs e)
149: {
150: WL("Nameserver_SignedOff");
151: ReConnect();
152: }
153:
154: static void Nameserver_SignedIn(object sender, EventArgs e)
155: {
156: messenger.Owner.Status = PresenceStatus.Online;
157: messenger.Owner.NotifyPrivacy = NotifyPrivacy.AutomaticAdd;
158: WL("Nameserver_SignedIn");
159: foreach (Contact contact in messenger.ContactList.Forward)
160: {
161: WL(contact.Name);
162: }
163: foreach (Contact contact in messenger.ContactList.Allowed)
164: {
165: WL(contact.Name);
166: }
167: foreach (Contact contact in messenger.ContactList.BlockedList)
168: {
169: WL(contact.Name);
170: }
171: messenger.Nameserver.SetPrivacyMode(PrivacyMode.AllExceptBlocked);
172: timer.Start();
173: }
174: static void Nameserver_PingAnswer(object sender, PingAnswerEventArgs e)
175: {
176: WL(e.SecondsToWait.ToString());
177: WL("Nameserver_PingAnswer");
178: }
179: static void SendPing()
180: {
181: messenger.NameserverProcessor.SendMessage(new PingMessage());
182: }
183: static void NameserverProcessor_ConnectionEstablished(object sender, EventArgs e)
184: {
185: WL("NameserverProcessor_ConnectionEstablished");
186: }
187:
188:
189: #region Helper methods
190:
191: private static void WL(object text, params object[] args)
192: {
193: Console.WriteLine(text.ToString(), args);
194: }
195:
196: private static void RL()
197: {
198: Console.ReadLine();
199: }
200:
201: private static void Break()
202: {
203: System.Diagnostics.Debugger.Break();
204: }
205:
206: #endregion
207: }
208: public class PingMessage : XihSolutions.DotMSN.Core.NSMessage
209: {
210: public override byte[] GetBytes()
211: {
212:
213: return System.Text.Encoding.UTF8.GetBytes("PNG\r\n");
214: }
215: }
216: }
例子下载,本文所使用的例子在MSNRobot工程中。2008/1/17 更新例子下载,解决出现的"您的主机中的软件放弃了一个已建立的连接"异常