Not logged in. · Lost password · Register
Forum: Jabber developers Jabber CZ & SK - vývoj software pro Jabber obecně
Jabber Client Library - v0.9rc2 [Roster]
Armoran #1
Member since Apr 2009 · 5 posts
Group memberships: Členové
Show profile · Link to this post
Subject: Jabber Client Library - v0.9rc2 [Roster]
Zdravím,
mám problém a celkem si sním už navím rady. Používám výše zmíněnou třídu (Jabber Client Library - v0.9rc2) pro systém podobnej klasickému chatBotu. A když projdu roster a zjištuju statusy vidím všechny z pohledu bota offlime přestože jsou online.

V handleru obsluhujícímu Authentication volám $this->jab->get_roster(); a poté zjištuju statusy v handleru volaném na událost "rosterupdate" procházením proměnné $this->jab->roster

Zkoušel jsem posílat presence ale to nepomohlo.

Děkuji všem za případné rady.

+ (Vcházel jsem z tohoto tutorialu: http://www.jazzychad.com/twitter/bots/)
Avatar
Pihhan #2
User title: Linuxák
Member since Apr 2003 · 262 posts · Location: Předklášteří
Group memberships: Členové
Show profile · Link to this post
Pokud voláte roster ihned po přihlášení a chcete po něm online stavy, velice pravděpodobně ani nemůžete dostat správné výsledky. Po přihlášení totiž obdržíte od každého odpověď na dotaz presence, který trvá nějakou dobu. Od lidí na lokálním serveru je to velmi brzy, ale i tak pravděpodobně stihnete číst stav ještě před tím, než jej doručí, takže logicky vidíte všechny offline. U kontaktů z jiných serverů může trvat pár vteřin ustavení s2s spojení, takže to může vzít klidně 10s, než uvidíte jeho stav (záleží na okolnostech, serveru, stavu sítě...). Možná by jste měl vědět, že roster update není to stejné jako obržení informaci o prezenci, alespoň ne v terminologii XMPP. Podle zběžného pohledu na odkazovanou stránku mám za to, že ani tam prezenci vůbec nezpracovává. Důležité je taky ukázat sebe online, protože obvykle až v reakci na to dostanete taky prezenci od ostatních. Tedy volat set_presence(), jak to autor dělá v návodu.

Obecně vás asi nepotěším, správa online stavů není úplně triviální, pokud se dělá pořádně. Je totiž třeba brát ohled na různá spojení při vícenásobném připojení, priority, etc... Ne že bych vás chtěl od práce odrazovat, ale možná by jste mohl zvážit použití třeba Pythonu nebo Perlu, pro XMPP má skoro jistě výrazně lepší podporu než PHP. Ale pravděpodobně to nějak řešit lze i v PHP, ale po rychlém prohlédnutí jabberclass jsem teda nezjistil zřejmý způsob, jak se to má dělat. Otázka je, jestli třeba http://code.google.com/p/xmpphp/ by nebyla lepší knihovna, kterou je to udělat ve výsledku snazší.
Armoran #3
Member since Apr 2009 · 5 posts
Group memberships: Členové
Show profile · Link to this post
Děkuji moc za radu, po příhlášení opravdu přišly presence od všech aktivních kontaktů a ja sem získal skutečné statusy, ale přišly pouze jednou. Pak po celou dobu běhu scriptu nepřišel ani jeden.

Jinak moc nechápu vlastní princip jak je to vymyšlené: Je to celé postavené na posílání presencí? Tedy dokud posílá presence je tam a je tedy tudíž nutno volat cyklicky metodu set_presence() tady konkrétně v handleHeartbeat která se volá každou vteřinu aby bylo bota vidět? Pak ale nechápu proč i ostatní klienti presence takto jednou za čas neposílají. A jakým způsobem ji z nich tedy "vyrazit".

Děkuji moc.
zenek (Administrator) #4
Member since Nov 2005 · 503 posts · Location: Bohumín
Group memberships: Administrátoři, Členové
Show profile · Link to this post
Z letmého pohledu na vámi odkazovanou stránku bych řekl, že je potřeba pomocí set_handler zaregistrovat obslužnou funkci pro příchozí presence, která se po příchozí změně presence zavolá a tam už si s ní můžete dle libosti pracovat.
Stop Skype Plague
zenek (Administrator) #5
Member since Nov 2005 · 503 posts · Location: Bohumín
Group memberships: Administrátoři, Členové
Show profile · Link to this post
Na druhou stranu, z trochu méně letmého pohledu bych řekl, že změna presence vyvolá zrovna ten rosterupdate, takže by stačilo obsluhu změn presencí udělat v něm.
Stop Skype Plague
Armoran #6
Member since Apr 2009 · 5 posts
Group memberships: Členové
Show profile · Link to this post
Děkuji moc za rady ale asi si nerozumíme, aspoň tak jak já to chápu, tak není problém ve zpracovvání příchozí presence, tu to totiž na začátku při připojení bota k serveru bez problému zpracuje a sesynchronizuje me to roster s daty v databázi, ale v tom že pak už mě to další presence nepošle.

Zachycení presence se podle mě děje přímo v execute (volání metody _handle_presence. A není potřeba ho nijak řešit.

tady je ukázka z logu (debug mode JabberClass): -ukázky příchozí presence od kontaktů v rosteru (tohle pčijde jen jednou na [1.] heartbeat)
DBG: RECV: <presence from="achse@njs.netlab.cz/Miranda" to="bot@mibac.cust.aspone.cz/Mibac AdminChat" xml:lang="en"><priority>0</priority><c xmlns="http://jabber.org/protocol/caps" node="http://miranda-im.org/caps" ver="0.8.0.22" ext="mood activity mir_notes"/><x xmlns="vcard-temp:x:update"><photo>5ae44003f602147adb5e068b9c798d0cea338e53</photo></x><status>Yep, I'm here.</status></presence>
DBG: RECV: <presence from="pepakriz@jabber.cz/Home" to="bot@mibac.cust.aspone.cz/Mibac AdminChat"><show>away</show><status>po baraku</status><c xmlns="http://jabber.org/protocol/caps" node="http://pidgin.im/caps" ver="2.5.5" ext="mood moodn nick nickn tune tunen avatarmeta avatardata bob avatar"/></presence>

Celý log tak jak mě vypadne po 10sec běhu bota je tady: http://pazderka.cz/achse_web/notes/jabberBot.log
Avatar
Pihhan #7
User title: Linuxák
Member since Apr 2003 · 262 posts · Location: Předklášteří
Group memberships: Členové
Show profile · Link to this post
Presence je vám poslána pouze při změně stavu vybraného kontaktu. Tedy po přihlášení vám dojde ode všech přihlášených online nebo away nebo podobně. Potom teprve až někdo z nich změní, například se odhlásí, nebo jeho klient změní stav na away, když nikdo nehýbe s myší, nebo jej změní sám uživatel.

Podle logu vám očividně nějaké prezence chodí, viz mirandovské Yum, I am here. Ale z logu není poznat, jestli tuto presenci nějak zpracováváte, jestli se při jejím doručení zanese do rosteru změna stavu. To už dost záleží na konkrétní implementaci, z logu obsluha patrná není. Není třeba nic dělat periodicky, XMPP je založen na TCP a až něco přijde, tak si to zpracujete. Polling není nutný, ani žádoucí. Pokud nemůžete nebo nechcete ukázat alespoň útržky kódu, jak přesně čtete z rosteru informaci o stavu, bude asi problém poradit. Zkuste napsat alespoň kousek kódu, jak kontrolujete, že je online.

Ono je taky otázka, jak má člověk vypsat online kontakty, když knihovna mu tyto stavy zpracovává sama. Potom nemáte callback, kde můžete vhodně zareagovat až poté, co přišla presence, protože ji nevidíte. Při procházení knihovny jsem narazil na $call_update = false, což podmiňuje volání rosterupdate z _handle_presence. Musím říct, že ta knihovna se mě nějak zvlášť nelíbí, ale snad by to s její pomocí mělo fungovat. Zkuste si udělat handler na zprávu, dejme tomu nějaký příkaz, a poslat botovi příkaz k vypsání online kontaktů. Tím zajistíte, že to nevypíše ihned po přihlášení ješte předtím, než dorazí roster a presence kontaktů. Zkuste prostě po pár vteřinách si zprávou vypsat stav uživatelů, co to udělá.
Armoran #8
Member since Apr 2009 · 5 posts
Group memberships: Členové
Show profile · Link to this post
Dekuji moc za rady. Už tedy chápu proč jsem já bota neviděl, a musel jsem presence posílat periodicky, když on nezpracoval informaci o mím stavu, ani já jsem tedy nedostal informaci o stavu jeho. Ale...

Já, jak jsem pochopil funcki té třídy, tak sama na packet obsahující presenci od nějakého kontaktu, vyvolá změnu rosteru ($jab->roster, resp. $this->jab->roster)  kde se upraví informace o 'show' a 'status'.

Tudíž by mělo stačit zavolat roster_update jen jedenkrát hned po authentication pro načtení kontaktů, a jejich stavy se časem, jakmile přijdou presence nastaví. (ta třída by měla sama volat _handle_presence
Viz metoda execute:
828: } elseif (!empty($packet['presence'])) {
829:     $this->_handle_presence($packet);

Tím pádem status kontroluji jen tím že procházím proměnou $this->jab->roster.
function checkOnline() {
    $sqlRoster = $this->sqlRoster;
    foreach ($this->jab->roster as $k=>$contact) {
        $con_name = $contact['jid'];
        if($con_name && $con_name[0]!='@') {
            echo "... $con_name - ".$contact['show']." (".$contact['status'].")<br />\n";
            //echo "___ ".$sqlRoster[$con_name]['status']." != ".$contact['show']."<br />\n";
            if($sqlRoster[$con_name]['status'] != $contact['show']) {
                $sqlRoster[$con_name]['status'] = $contact['show'];
                mysql::update("adminchat_roster", "status='".$contact['show']."'", "JID='".$contact['name']."'");
                echo "... [!!!] sqlRoster UPDATED!<br />\n";
            }
        }
    }
    $this->sqlRoster = $sqlRoster;
}

A tohle volám v handleHeartbeat():
function handleHeartbeat() {
    $this->upTime++;
    echo "[x] [".$this->upTime."] My heart beats only for you!<br />\n";
    $this->sendMessages();
    //$this->jab->set_presence("on",$this->presence);
    //$this->jab->get_roster();
    $this->checkOnline();
  }
This post was edited on 2009-05-10, 17:45 by Armoran.
Avatar
Pihhan #9
User title: Linuxák
Member since Apr 2003 · 262 posts · Location: Předklášteří
Group memberships: Členové
Show profile · Link to this post
Ověřte, jestli v rosteru nejsou prezence ukládány i s resource, kde by potom nemuselo nutně odpovídat kontaktům z kontakt listu. Čili jestli jsou v rosteru uloženy ve formě user@domain, nebo user@domain/resource. U kontaktů je zvykem ukládat je jenom user@domain, u prezencí se ale posílá s plným jid i s přidaným zdrojem, aby to obsluhovalo vícenásobné přihlášení. Po letmém průletu knihovnou jsem neviděl žádné odsekávání zdroje nebo převedení na bare formu, ale nezkoumal jsem to zas tak důkladně. Zkuste ale vylistovat obsah presence_cache, třeba tam bude něco zajímavého. Ale vlastního bota jsem psát v PHP nezkoušel, takže třeba to nečtu správně. Pokud ale jádro bota má být sledování presence, možná bych použil přímo implementaci vlastního handleru na presenci s uložením do SQL přímo z něj, takhle je to takové drbání za uchem palcem od nohy.

Update: tak resource osekávány jsou, tím to asi nebude, ale měl by jste vědět, že vícenásobné připojení to tím pádem neumí zobrazit správně. Pokud se např. napřed připojíte z PC, potom z mobilu, z PC se odhlásíte, tenhle bot podle mě bude hlásit kontakt offline (poslední update presence byl z PC), i když na mobilu stále jsem. Resource jsou komplikace i síla jabberu zároveň, pokud ale myslíte tu službu vážně, doporučuju s nimi počítat a obsluhovat je trochu reálně.
Armoran #10
Member since Apr 2009 · 5 posts
Group memberships: Členové
Show profile · Link to this post
Děkuji moc, už jsem to vyřešil, problém byl rosteru, nevím do teď proč ale jabber class každou presenci která přišla vyhodnotila jako od "not in roster" a zahazovala do vámi zmíněné presence_cache. takže jsem tu kontrolu prostě vyřadil, pro moje potřeby stejně není třeba, a vše funguje jak má.

Ještě jednou děkuji moc za rady.
This post was edited on 2009-05-12, 22:48 by Armoran.
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please note the verification code from the picture into the text field next to it.
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Go to forum
This board is powered by the Unclassified NewsBoard software, 1.6.4, © 2003-7 by Yves Goergen
Current time: 2012-02-07, 18:22:30 (UTC +02:00)