10. diel - Trieda pre prácu s agsXMPP, Adaptee Wrapper pre XMPP - isim
Pre XMPP používam agsXMPP: http://www.ag-software.de/...dk/download/
Pre použitie tejto knižnice mám nasledujúce triedu:
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); } }
Tu je konečne ukážka adaptee Wrapper v praxi, ale najkrajšie 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; } } } }