发了几篇与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:
}