Jak získat on-line status zvoleného ICQ uživatele

10. května 2007

O autorovi

Portrét

Jan Aubrecht
.NET vývojář a konzultant IS/IT
honza@intellisoft.cz

Honza se zabývá vývojem webových aplikací od roku 2000. Rád používá ASP.NET 2.0 a je přímo posedlý neustálým zlepšováním svých aplikací.

Ve volném čase je jeho vášní dobré jídlo a pití. Nejraději se baví přípravou středomořských specialit a báječnými víny z Francie.

Soubory ke stažení

Zdrojové kódy použité v článku a další související soubory si můžete stáhnout zde:

Další články

Článek vám ukáže jednoduchý trik, jak získat on-line status zadaného ICQ uživatele. S využitím jednoduché třídy, kterou si vytvoříme, pak můžete zobrazovat informace o stavu připojení daného uživatele v libovolné .NET aplikaci.

Jak získat aktuální status?

ICQ status daného uživatele je možné získat hned dvěma způsoby. Prvním z nich je použití ICQ protokolu.

Pokud bychom chtěli zjistit status uživatele pomocí ICQ protokolu, musíme se nejdříve připojit k některému ze serverů v síti ICQ a přihlásit se pod platným UIN. Po úspěšném přihlášení se můžeme serveru zeptat na status daného uživatele.

Z popisu tedy vyplývá, že se status uživatele ověřuje stejným způsobem, jaký používá i samotný ICQ klient.

Bohužel to vše je jen hezká teorie, protože ICQ protokol je poměrně složitý, čas od času se jeho části mění a navíc k němu neexistuje žádná oficiální dokumentace.

Pojďme se tedy podívat na druhý způsob, jak zjistit on-line status ICQ uživatele.

Zjišťujeme status pomocí HTTP

Možná víte, že jednou z doplňkových služeb ICQ je možnost používat na svých webových stránkách tzv. ICQ Status Indicator. Indikátor není nic jiného než obrázek, který grafickou formou informuje návštěvníka webu, zda-li je uživatel on-line a nebo off-line.

Ten samý indikátor využijeme v našem řešení, abychom programově zjistili uživatelův on-line status.

Jediné co nás trochu omezuje v použití, je skutečnost, že daný ICQ uživatel musí mít ve svém profilu povoleno zobrazení stavu na webu. Pokud ho nebude mít povolené, bude indikátor zobrazovat obrázek "Indicator Disabled" a nám se nepodaří jeho status získat.

Vytváříme třídu IcqUtility

Naše třída pro zjištění on-line stavu bude opravdu velmi jednoduchá.

Bude obsahovat pouze jednu statickou metodu (včetně jedné její přetížené varianty), která nám po zadání UIN daného uživatele vrátí jeho on-line status.

Pro uložení stavu použijeme enumeraci, která bude specifikovat, zda je uživatel on-line, off-line a nebo že se jeho status nepodařilo zjistit.

Princip, jak budeme zjišťovat on-line status uživatele, je velmi jednoduchý. Pouze se připojíme k webovému serveru ICQ a požádáme ho o obrázek indikující stav daného uživatele. Podle datové velikosti obrázku pak zjistíme, jestli je uživatel on-line nebo off-line.

Kód metody, která se připojí k webovému serveru a vrátí velikost staženého obrázku, vypadá následovně:

private static int GetImageLength(string url, int timeout)
{
    HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
 
    request.Timeout = timeout;
    request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
 
    using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
    {
        using (Stream stream = response.GetResponseStream())
        {
            int length = 0;
 
            while (stream.ReadByte() != -1)
            {
                length++;
            }
            return length;
        }
    }
}

Nyní se můžeme pustit do psaní metody, která podle velikosti obrázku vrátí příslušný on-line status. Kód metody nebude nijak složitý. Metoda pouze sestaví URL pro status indikátor daného uživatele a pomocí metody GetImageLength získá velikost obrázku, který indikuje aktuální on-line status. Podle jeho velikosti pak vrátí příslušný stav reprezentovaný enumerací IcqStatus.

///<summary>The size of the offline image in bytes.</summary>
private const int OfflineLength = 1963;
 
///<summary>The size of the online image in bytes.</summary>
private const int OnlineLength = 1281;
 
///<summary>The URL of the ICQ status indicator.</summary>
private const string RequestUrl = "http://status.icq.com/online.gif?icq={0}";
 
public static IcqStatus GetStatus(int uin, int timeout)
{
    if (uin < 0)
        throw new ArgumentOutOfRangeException("uin");
 
    if (timeout < 0)
        throw new ArgumentOutOfRangeException("timeout");
 
    int length = 0;
 
    try
    {
        length = GetImageLength(string.Format(RequestUrl, uin), timeout * 1000);
    }
    catch (WebException)
    {
        //Ignore the request timeout.
    }
 
    switch (length)
    {
        case OnlineLength:
            return IcqStatus.Online;
 
        case OfflineLength:
            return IcqStatus.Offline;
 
        default:
            return IcqStatus.Unknown;
    }
}

Třídu můžete začít používat v libovolné .NET aplikaci. Její použití je opravdu jednoduché:

if (IcqUtility.GetStatus(29547754) == IcqStatus.Online)
    MessageBox.Show("Uživatel je on-line.");
else
    MessageBox.Show("Uživatel je off-line.");

Kompletní zdrojový kód třídy IcqUtility si můžete stáhnout zde.