IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 10 - Třída pro práci s agsXMPP, Adaptee Wrapper pro XMPP - ISIM

Pro XMPP používám agsXMPP: http://www.ag-software.de/…dk/download/

Pro použití této knihovny mám následující třídu:

public class XmppClass
{
    public string protocolName;
    private Jid userJid;
    private string userPassword;
    private string serverDomain;
    public XmppClientConnection xmppClient = new XmppClientConnection();

    public XmppClass(string protocolName, string userJid, string userPassword, string serverDomain = null)
    {
        this.protocolName = protocolName;
        this.userJid = new Jid(userJid);
        this.userPassword = userPassword;
        this.serverDomain = serverDomain;

        xmppClient.Server = this.userJid.Server;
        // tohle se u normálních xmpp (jabber, g+ atp) objevuje nějak takto -> ::ISIM::ads48e8df (ňáký uniqid) u fb se nezobrazí nic
        xmppClient.Resource = "::ISIM::";

        // tohle vůbec, ale vůbec nefunguje
        xmppClient.AutoPresence = true;
        xmppClient.AutoResolveConnectServer = true;
        xmppClient.AutoRoster = true;
        xmppClient.KeepAlive = true;
        xmppClient.KeepAliveInterval = 60;
        xmppClient.SocketConnectionType = agsXMPP.Net.SocketConnectionType.Direct;

        xmppClient.OnXmppConnectionStateChanged += new XmppConnectionStateHandler(xmpp_OnXmppConnectionStateChanged);
        xmppClient.OnPresence += new PresenceHandler(xmpp_OnPresence);
        xmppClient.OnAuthError += new XmppElementHandler(xmpp_OnAuthError);
        xmppClient.OnMessage += new MessageHandler(xmpp_OnMessage);

        xmppClient.OnRosterStart += new ObjectHandler(xmppClient_OnRosterStart);
        xmppClient.OnRosterItem += new XmppClientConnection.RosterHandler(xmpp_OnRosterItem);
        xmppClient.OnRosterEnd += new ObjectHandler(xmppClient_OnRosterEnd);
    }


    /// <summary>
    /// Vytvoří připojení s xmpp serverem a požádá o kontakt list (request roster)
    /// </summary>
    public void connect()
    {
        xmppClient.Open(userJid.User, userPassword);
        xmppClient.OnLogin += xmppClient_OnLogin;
    }

    /// <summary>
    /// Při připojení se oznámí presence
    /// </summary>
    /// <param name="sender"></param>
    void xmppClient_OnLogin(object sender)
    {
        Presence pres = new Presence(ShowType.chat, "Online");
        pres.Type = PresenceType.available;
        xmppClient.Send(pres);

        Console.WriteLine("in xmpp class" + userJid.Server);
    }

    /// <summary>
    /// Zablokuju refreshování contact listu, počkám až se načtou všechny kontakty a on roster end to teprve refreshnu
    /// </summary>
    /// <param name="sender"></param>
    void xmppClient_OnRosterStart(object sender)
    {
        try
        {
            Global.OpenForms.mainForm.contactListView.Invoke(new System.Windows.Forms.MethodInvoker(delegate()
            {
                Global.OpenForms.mainForm.contactListView.BeginUpdate();
            }));
        }
        catch (InvalidOperationException)
        { }
    }

    /// <summary>
    /// Refresh kontakt listu
    /// </summary>
    /// <param name="sender"></param>
    void xmppClient_OnRosterEnd(object sender)
    {
        try
        {
            Global.OpenForms.mainForm.contactListView.Invoke(new System.Windows.Forms.MethodInvoker(delegate()
            {
                Global.OpenForms.mainForm.contactListView.EndUpdate();
            }));
        }
        catch (InvalidOperationException)
        { }
    }

    /// <summary>
    /// Vrací kontakty ze server kontakt listu
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="item"></param>
    void xmpp_OnRosterItem(object sender, RosterItem item)
    {
        // pokud to nejsu já nebo nemám týpka v kontaktech (buddy)
        if (((protocolName == "gtalk") && (item.Subscription == SubscriptionType.none)) || ((item.Jid.User == userJid.User) && (item.Jid.Server == userJid.Server)))
            return;

        addContact(item);
    }

    /// <summary>
    /// Přidání kontaktu do kontaktlistu
    /// </summary>
    /// <param name="i"></param>
    private void addContact(RosterItem i)
    {
        if (protocolName == "gtalk")
            Console.WriteLine("adding before invoke" + i.Name);
        if ((i.Name == null) || (i.Name.Replace(" ", "").Length == 0))
            i.Name = i.Jid.Bare;

        Global.OpenForms.mainForm.contactListView.BeginInvoke(new System.Windows.Forms.MethodInvoker(delegate()
        {
            if (Global.OpenForms.mainForm.contactListView.Items.ContainsKey(i.Jid.Bare))
            {
                try
                {
                    if (Global.OpenForms.mainForm.contactListView.Items[i.Jid.Bare].Text == i.Jid.Bare)
                    {
                        (Global.OpenForms.mainForm.contactListView.Items[i.Jid.Bare] as ContactListViewItem).contact.name = i.Name;
                        Global.OpenForms.mainForm.contactListView.Items[i.Jid.Bare].Text = i.Name;
                        Console.WriteLine("renaming contact");
                    }
                }
                catch (NullReferenceException)
                {
                    Console.WriteLine("cannot rename" + i.Name);
                }
            }
            else
            {
                if (protocolName == "gtalk")
                    Console.WriteLine("adding" + i.Name);
                Global.ISIMFunctions.AddContact(new XmppContact(i.Jid.Bare, i.Name, new XmppContact.ContactObject(protocolName), protocolName));
            }
        }));
    }

    /// <summary>
    /// Změna dostupnosti uživatele
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="pres"></param>
    private void xmpp_OnPresence(object sender, Presence pres)
    {
        if ((pres.From == null) || ((pres.From.User == userJid.User) && (pres.From.Server == userJid.Server)))
            return;

        if (pres.Type == PresenceType.subscribe)
        {
            PresenceManager pm = new PresenceManager(xmppClient);
            // abych řekl pravdu, tuhle zprávu sem nikdy neviděl
            if (System.Windows.Forms.MessageBox.Show("Požadavek na autorizaci: " + pres.From + "\nAutorizovat?", "Požadavek na autorizaci", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Exclamation, System.Windows.Forms.MessageBoxDefaultButton.Button1) == System.Windows.Forms.DialogResult.Yes)
                pm.ApproveSubscriptionRequest(pres.From);
            else
                pm.RefuseSubscriptionRequest(pres.From);
        }

        Console.WriteLine("presence:" + pres.From);

        Global.OpenForms.mainForm.contactListView.BeginInvoke(new System.Windows.Forms.MethodInvoker(() =>
        {
            try
            {
                if (!Global.OpenForms.mainForm.contactListView.Items.ContainsKey(pres.From.Bare))
                {
                    Global.ISIMFunctions.AddContact(new XmppContact(pres.From.Bare, pres.From.Bare, new XmppContact.ContactObject(protocolName), protocolName, pres.Type));
                }
            }
            catch (InvalidOperationException)
            { }
        }));

        if (pres.Show.ToString() == "away") pres.Type = PresenceType.probe;
        if (pres.Show.ToString() == "dnd") pres.Type = PresenceType.subscribe;

        if (!Global.Converter.AvatarExists(pres.From.Bare))
            Global.ISIMFunctions.GetXmppContactAvatar(xmppClient, pres.From);

        Global.ISIMFunctions.EditContactAvailability(pres.From.Bare, Global.Converter.GetContactAvailability(pres.Type));
    }

    /// <summary>
    /// Příchozí zpráva
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="msg"></param>
    private void xmpp_OnMessage(object sender, Message msg)
    {
        // got JID -> msg.from
        if ((msg.Body != null) && (msg.Body.Replace(" ", "").Length > 0))
        {
            Global.OpenForms.mainForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
            {
                ISIMContact contact;
                if (Global.OpenForms.mainForm.contactListView.Items.ContainsKey(msg.From.Bare))
                    contact = (Global.OpenForms.mainForm.contactListView.Items[msg.From.Bare] as ContactListViewItem).contact;
                else
                    contact = new XmppContact(msg.From.Bare, msg.From.Bare, new XmppContact.ContactObject(protocolName), protocolName);

                Global.ISIMFunctions.AddChatMessage(contact, msg.Body, DateTime.Now, contact.name);
            }));
        }
    }

    /// <summary>
    /// Změna dostupnosti, vykopli mě hajzli jedni to jim de, nebo sem se přihlásil to jim zas trvá, etc
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="state"></param>
    private void xmpp_OnXmppConnectionStateChanged(object sender, XmppConnectionState state)
    {
        switch (state)
        {
            case XmppConnectionState.Disconnected:
                Console.WriteLine("xmpp disconnected");

                if (Global.OpenForms.mainForm.contactListView.InvokeRequired)
                {
                    try
                    {
                        Global.OpenForms.mainForm.contactListView.Invoke(new System.Windows.Forms.MethodInvoker(delegate()
                        {
                            foreach (ContactListViewItem item in Global.OpenForms.mainForm.contactListView.Items)
                            {
                                if (item.contact.protocol == protocolName)
                                {
                                    Global.ISIMFunctions.EditContactAvailability(item.contact.id, Global.Availability.Offline);
                                }
                            }
                        }));
                    }
                    catch (InvalidOperationException)
                    { }
                }
                break;
            case XmppConnectionState.Connected:
                Console.WriteLine("xmpp connected waiting for auth");
                break;
            case XmppConnectionState.SessionStarted:
                Console.WriteLine("xmpp " + protocolName + " sucessfuly connected");

                break;
            default:
                Console.WriteLine("xmpp state:" + state.ToString());
                break;
        }
    }

    /// <summary>
    /// Většinou špatnej login
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void xmpp_OnAuthError(object sender, Element e)
    {
        Console.WriteLine("xmpp - wrong login");

        System.Windows.Forms.MessageBox.Show("Selhalo připojení. Zkontroluj přihlašovací údaje.");
    }

    /// <summary>
    /// Odhlášení se od xmpp serveru
    /// </summary>
    public void disconnect()
    {
        Presence p = new Presence(ShowType.chat, "Offline");
        p.Type = PresenceType.unavailable;
        xmppClient.Send(p);

        this.xmppClient.Close();
        Console.WriteLine("disconnected from" + userJid.Server);
    }
}

Zde je konečně ukázka adaptee wrapperu v praxi, ale nejhezčí je to u Skype.

public class XmppContact : ISIMContact
{
    string _identificator;
    ContactObject _contactObject;
    string _protocolName;

    public XmppContact(string jid, string name, ContactObject contactObject, string protocolName, PresenceType presence = PresenceType.error)
    {
        _identificator = jid;
        this.name = name;
        availability = Global.Converter.GetContactAvailability(presence);
        _contactObject = contactObject;

        _protocolName = protocolName;
    }

    public string id
    {
        get { return _identificator; }
    }

    public string name
    {
        get;
        set;
    }

    public Global.Availability availability
    {
        get;
        set;
    }

    public object contactObject
    {
        get { return _contactObject; }
    }


    public string protocol
    {
        get { return _protocolName; }
    }

    public bool unreadedMessage { get; set; }

    public class ContactObject
    {
        private XmppClientConnection _xmppClient;
        private string protocolName;

        public ContactObject(string protocolName)
        {
            this.protocolName = protocolName;
        }

        public XmppClientConnection xmppClient
        {
            get
            {
                Global.OpenForms.mainForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
                {
                    if (protocolName == "facebook")
                        _xmppClient = Global.OpenForms.mainForm.fb.xmppClient;
                }));

                return _xmppClient;
            }
        }
    }
}

 

Předchozí článek
Upravené komponenty: TabControl, TabPage, RTB - ISIM
Všechny články v sekci
Programujeme vlastní Instant Messenger ::ISIM::
Přeskočit článek
(nedoporučujeme)
Třída pro práci s ICQ#, ICQ kontakt - ISIM
Článek pro vás napsal David Jančík
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
Autor je vášnivý programátor. Nezná slovo "nelze", nebojí se zkoušet nepoznané a pronikat do nových technologií.
Aktivity