利用程式發送 MSN 訊息
要偵測伺服器是否掛點,可以用 .NET 的 TcpClient 嘗試連接伺服器的特定 port,這種簡單的方法不僅可以用在 Web 伺服器,也可以用於資料庫伺服器(例如:嘗試連接 Oracle 伺服器的 1521 port)。
一旦發現伺服器無法正常運作,程式可以發送 mail 通知系統管理員,可是系統管理員不見得會經常收信,這樣的時效性就不夠快。現在 MSN messenger 已經很普遍,如果發現系統出問題時,能夠發即時訊息給相關人員,似乎是個不錯的辦法。
這裡我用來發送 MSN 即時訊息的元件是 MSNPSharp。這個元件有附一個 Windows Forms 範例程式可以參考,此範例就像一個陽春型的 MSN Messenger,可以讓你登入 MSN 伺服器、發送訊息給聯絡人等等。
仔細研究這個範例程式,大概就可以瞭解 MSNPSharp 的基本用法,同時也可以發現,此元件大量運用了非同步處理的程式撰寫模型。這種非同步的撰寫方式不僅增加了學習門檻,除錯也比較麻煩,更重要的是,這並不是我想要的。
我的需求很簡單:當程式需要發送 MSN 訊息時,就先登入 MSN 伺服器,然後依事先設定的聯絡人逐一發送文字訊息。訊息發送的對象有可能是離線狀態,這沒關係,繼續發送給下一位聯絡人即可。
針對上述需求,我寫了一個簡單的 wrapper 類別:SimpleMsnMessenger。這裡我不打算詳細說明原理,謹列出幾個重點步驟:
- 建立 Messenger 物件 => messenger。
- 利用 messenger.Connect() 登入伺服器。
關鍵事件:messenger.Nameserver.SignedIn - 利用 messenger.CreateConversation() 建立 Conversation 物件 => conversation。
關鍵事件:messenger.ConversationCreated - 利用 conversation.Invite(("someone@hotmail", ClientType.PassportMember); 邀請對方加入對話。
關鍵事件:conversation.Switchboard.ContactJoined (已成功邀請對方加入對話) - 利用 conversation.SwitchBoard.SendTextMessage() 發送文字訊息。
SimpleMsnMessenger 的完整程式碼可按此連結下載。Note: 此程式碼還有許多改進空間,尤其是錯誤處理的部分,但基本上還堪用。
以下是使用此 wrapper class 的範例:
class ServerAliveChecker
{
private SimpleMsnMessenger msn = new SimpleMsnMessenger("robot@hotmail.com", "password");
private void SendMsn(StringBuilder text)
{
string receivers = ConfigurationManager.AppSettings["ReceiverMsn"];
if (String.IsNullOrEmpty(receivers))
{
return;
}
lblStat.Text = "正在傳送 MSN 訊息...";
Application.DoEvents();
string[] msnMail = receivers.Split(';');
try
{
msn.Connect();
// 等待登入動作完成。
while (msn.IsConnecting && msn.ErrorCount <= 0)
{
Application.DoEvents();
}
if (msn.Connected && msn.SignedIn)
{
// 登入成功
foreach (string mail in msnMail)
{
msn.SendTextMessage(mail, text.ToString());
}
// 等待訊息全部發完,但只等待一段時間。
DateTime now = DateTime.Now;
while (!msn.MessageQueueEmpty)
{
Application.DoEvents();
System.Threading.Thread.Sleep(500);
TimeSpan ts = DateTime.Now.Subtract(now);
if (ts.Minutes >= 3)
{
break;
}
}
msn.Disconnect();
}
else
{
string err = "MSN Messenger 登入失敗";
if (msn.ErrorCount > 0)
{
LogError(err + ": " + msn.LastError.Message);
}
else
{
LogError(err + "。" + msn.LastError.Message);
}
return;
}
}
catch (Exception ex)
{
LogError(ex.ToString());
}
}
}
按此連結下載完整的類別與範例原始碼
