利用程式發送 MSN 訊息

會寫這個程式,主要是因為一個重要的 Web 應用程式三不五時會掛掉,而系統管理員希望能在第一時間發現這個情況(以免使用者來電開罵)。

要偵測伺服器是否掛點,可以用 .NET 的 TcpClient 嘗試連接伺服器的特定 port,這種簡單的方法不僅可以用在 Web 伺服器,也可以用於資料庫伺服器(例如:嘗試連接 Oracle 伺服器的 1521 port)。

一旦發現伺服器無法正常運作,程式可以發送 mail 通知系統管理員,可是系統管理員不見得會經常收信,這樣的時效性就不夠快。現在 MSN messenger 已經很普遍,如果發現系統出問題時,能夠發即時訊息給相關人員,似乎是個不錯的辦法。

這裡我用來發送 MSN 即時訊息的元件是 MSNPSharp。這個元件有附一個 Windows Forms 範例程式可以參考,此範例就像一個陽春型的 MSN Messenger,可以讓你登入 MSN 伺服器、發送訊息給聯絡人等等。

仔細研究這個範例程式,大概就可以瞭解 MSNPSharp 的基本用法,同時也可以發現,此元件大量運用了非同步處理的程式撰寫模型。這種非同步的撰寫方式不僅增加了學習門檻,除錯也比較麻煩,更重要的是,這並不是我想要的。

我的需求很簡單:當程式需要發送 MSN 訊息時,就先登入 MSN 伺服器,然後依事先設定的聯絡人逐一發送文字訊息。訊息發送的對象有可能是離線狀態,這沒關係,繼續發送給下一位聯絡人即可。

針對上述需求,我寫了一個簡單的 wrapper 類別:SimpleMsnMessenger。這裡我不打算詳細說明原理,謹列出幾個重點步驟:
  1. 建立 Messenger 物件 => messenger。
  2. 利用 messenger.Connect() 登入伺服器。
    關鍵事件:messenger.Nameserver.SignedIn
  3. 利用 messenger.CreateConversation() 建立 Conversation 物件 => conversation。
    關鍵事件:messenger.ConversationCreated
  4. 利用 conversation.Invite(("someone@hotmail", ClientType.PassportMember); 邀請對方加入對話。
    關鍵事件:conversation.Switchboard.ContactJoined (已成功邀請對方加入對話)
  5. 利用 conversation.SwitchBoard.SendTextMessage() 發送文字訊息。
有興趣研究的朋友可以參考這篇文章:MSNPSharp傳送信息程序詳解,大致瞭解其設計原理後,再對照範例程式來研究,應該就比較容易瞭解 MSNPSharp 的基本用法。

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());

}

}

}



按此連結下載完整的類別與範例原始碼

Post Comments

技術提供:Blogger.