Jak získat on-line status zvoleného ICQ uživatele
10. května 2007
O autorovi
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:
Č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.