飯否網站MSN機器人實現原理及代碼

飯否,唧歪們MSN、QQ、GTalk機器人實現原理及代碼
----飯否,唧歪MSN機器人實現原理(DotMSN2.0解析篇,以下代碼作者全部測試通過)

騰訊滔滔近期發佈,各大IT網站爭相報道
最後的結論是滔滔不會做MSN、GTalk機器人,所以飯否、唧歪類網站在騰訊入侵後仍然有生存的餘地。
twitter模式,即迷你博客網站的興起、流行主要是因爲接入方法多樣
我們打開這些網站,可以發現迷你博客內容的發佈多數不是來自網頁,超過半數是來自IM
因爲IM是互聯網發展到現在非常成功的一個產品,其中QQ、MSN、GTalk佔有絕對優勢
我們的網民每天上網都會使用IM,而飯否、唧歪類網站是第一批開始藉助IM運作的互聯網產品
飯否是目前國內模仿twitter模式較爲成功的,我們以飯否爲例,IM我們以MSN爲例
我們可以通過MSN接入飯否做以下事情,首先加飯否的MSN機器人爲好友,記我的MSN帳號爲A,飯否機器人MSN帳號爲B,我在飯否加了一個好友爲C:
1.A打開B,輸入“H”,即A發送消息“H”給B,B馬上把使用幫助信息發送給A
2.A打開B,輸入其他字符串,馬上飯否網站A的迷你博客有了一條新的,內容是這個字符串
3.C在飯否通過一種方式發佈了一個迷你博客,A這時在用MSN,B爲主動發送一個消息給A,消息內容是:C發佈了迷你博客“迷你博客內容”
具體到技術層面,這些功能是怎麼實現的呢?
微軟公司的MSN,現在叫做Live Messager,提供了開發接口,通過更容易做二次開發的當推DotMSN2.0
開發平臺爲Visual Studio 2005,基於.net 2.0

我們對DotMSN2.0源代碼進行了分析、改造,現總結如下:
先通過改造後的程序功能介紹讓列位看官有一個感性的認識
整個應用程序有2個主體類
public partial class Robot : Form
//界面,實現機器人MSN帳號的登錄,以及定時讀取數據庫
class MyConversation
//實現機器人與好友對話的功能
//Robot的實現:
// Create a Messenger object to use DotMSN.
private XihSolutions.DotMSN.Messenger messenger = new Messenger();
//構造函數
public Robot()
{
    InitializeComponent();
        // by default this example will emulate the official microsoft windows messenger client
        messenger.Credentials.ClientID = "[email protected]";
        messenger.Credentials.ClientCode = "Q1P7W2E4J9R8U3S5";
    //登錄成功之後觸發事件
        messenger.NameserverProcessor.ConnectionEstablished += new EventHandler(NameserverProcessor_ConnectionEstablished);
        messenger.Nameserver.SignedIn += new EventHandler(Nameserver_SignedIn);
        messenger.ConversationCreated += new ConversationCreatedEventHandler(messenger_ConversationCreated);
}
//MSN機器人登錄函數
private void login_Click(object sender, EventArgs e)
{
            if (messenger.Connected)
            {
                SetStatus("Disconnecting from server");
                messenger.Disconnect();
            }
            // set the credentials, this is ofcourse something every DotMSN program will need to
            // implement.
            messenger.Credentials.Account = account.Text;
            messenger.Credentials.Password = password.Text;

            // inform the user what is happening and try to connecto to the messenger network.           
            SetStatus("Connecting to server");
            messenger.Connect();
            // note that Messenger.Connect() will run in a seperate thread and return immediately.
            // it will fire events that informs you about the status of the connection attempt.
            // these events are registered in the constructor.
}
//Robot Form定時器執行函數
private void Timer_Tick(object sender, EventArgs e)
{           
    //遍歷MSN機器人的所有好友
            foreach (Contact contact in messenger.ContactList.All)
            {
                if (contact != null && contact.Online == true)
                {
        //實例化一個機器人與好友的對話
                    Conversation conversation = messenger.CreateConversation();
                    conversation.Invite(contact);//邀請好友參與對話
                    MyConversation agent = CreateMyConversation(conversation);//實例化一個對話處理                   
                }
            }
}
//對話處理的實例化(這個很關鍵)
    /// <summary>
        /// A delegate passed to Invoke in order to create the conversation form in the thread of the main form.
        /// </summary>
        private delegate MyConversation CreateConversationDelegate(Conversation conversation);

        private MyConversation CreateMyConversation(Conversation conversation)
        {
            // create a new conversation. However do not show the window untill a message is received.
            // for example, a conversation will be created when the remote client sends wants to send
            // you a file. You don't want to show the conversation form in that case.
            MyConversation agent = new MyConversation(conversation);

            // do this to create the window handle. Otherwise we are not able to call Invoke() on the
            // conversation form later.
            //agent.Handle.ToInt32();

            return agent;
        }
//如果是第一次好友主動向MSN機器人發送消息,則調用
        private void messenger_ConversationCreated(object sender, ConversationCreatedEventArgs e)
        {
            // check if the request is initiated remote or by this object
            // if it is initiated remote then we have to create a conversation form. Otherwise the
            // form is already created and we don't need to create another one.
            if (e.Initiator == null)
            {
                // use the invoke method to create the form in the main thread
                this.Invoke(new CreateConversationDelegate(CreateMyConversation), new object[] { e.Conversation });
            }
        }
//再來看看class MyConversation
    private Conversation _conversation;

        /// <summary>
        /// The conversation object which is associated with the form.
        /// </summary>
        public Conversation Conversation
        {
            get { return _conversation; }
        }
        public MyConversation(Conversation conversation)
        {
            _conversation = conversation;
    //綁定事件,處理好友發送消息給MSN機器人
            Conversation.Switchboard.TextMessageReceived += new TextMessageReceivedEventHandler(Switchboard_TextMessageReceived);
            Conversation.Switchboard.SessionClosed += new SBChangedEventHandler(Switchboard_SessionClosed);
            Conversation.Switchboard.ContactJoined += new ContactChangedEventHandler(Switchboard_ContactJoined);
            Conversation.Switchboard.ContactLeft += new ContactChangedEventHandler(Switchboard_ContactLeft);
        }   
    //MSN機器人給好友發送消息
        public void SendInput(String inputMessage)
        {
            // check whether there is input
            if (inputMessage.Length == 0) return;

            // if there is no switchboard available, request a new switchboard session
            if (Conversation.SwitchboardProcessor.Connected == false)
            {
                Conversation.Messenger.Nameserver.RequestSwitchboard(Conversation.Switchboard, this);
            }

            // note: you can add some code here to catch the event where the remote contact lefts due to being idle too long
            // in that case Conversation.Switchboard.Contacts.Count equals 0.           

            TextMessage message = new TextMessage(inputMessage);

            /* You can optionally change the message's font, charset, color here.
             * For example:
             * message.Color = Color.Red;
             * message.Decorations = TextDecorations.Bold;
             */

            Conversation.Switchboard.SendTextMessage(message);
        }
    private void Switchboard_ContactJoined(object sender, ContactEventArgs e)
        {
            SendInput("定時發送的消息");//實現MSN機器人向好友主動推送消息
        }
    private void PrintText(string name, string text)
        {
             if (text.ToLower().Equals("h"))
            {
                SendInput("幫助命令如下:/r輸入“on”接收朋友信息/r輸入“off”停止接收朋友信息/r輸入“@用戶名+空格+內容”給某人發送信息/r輸入“*用戶名+空格+內容”給某人發送悄悄話/r輸入“find+空格+關鍵字”查詢用戶/r輸入“add+空格+用戶名”添加某人爲好友/r輸入其他信息則發送到有趣吧。");
            }
        }
    //MSN機器人接收消息
        private void Switchboard_TextMessageReceived(object sender, TextMessageEventArgs e)
        {
            PrintText(e.Sender.Name, e.Message.Text);                  
        }

通過以上程序,即對dotmsn2.0實例代碼的改造,初步實現了類似飯否、唧歪這些仿twitter的MSN機器人
我們結合上面的程序,再來看看飯否的MSN機器人
1.我們的MSN輸入h給機器人,機器人可以把一個固定的字符串發過來,這就對應上面代碼的Switchboard_TextMessageReceived模塊;
2.我們輸入其他信息給機器人,還是這個模塊,只不過繼續改裝把這個消息數據寫入到飯否的數據庫;
3.我們的好友在飯否發佈了消息,MSN機器人會馬上主動把這個消息推送給我,這個怎麼實現呢?
上面我給出的代碼,Timer時間間隔設置爲2秒,然後 Timer_Tick繼續改造
先讀取數據庫,看有沒有新的消息,如果有,則把這個消息發送者的關注者(並且綁定了MSN)形成一個MSN用戶列表
這些用戶肯定是MSN機器人的好友,於是下面可以把這個消息主動推送給這些用戶,其他功能類似。

遺憾的是,在DotMSN2.0中還沒有找到MSN用戶個性簽名變化引發的消息,希望列位看官有知道的給予補充。

這篇博文介紹了飯否類網站MSN機器人的實現
而GTalk機器人實現更爲簡單,因爲Google公佈了GTalk的協議以及開發文檔,後面的文章會進行介紹
那麼QQ機器人是怎麼做的呢?我們研究了linux平臺下的lumaqq源代碼,並進行改造,後面的文章也會介紹QQ機器人是怎麼實現,敬請關注。

另外MSN機器人會在我們的網站有趣吧(http://www.youqubar.com)使用,只要你添加我們的MSN機器人爲好友
這個機器人會主動推送網站上新的趣圖給您,敬請關注。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章