J2ME pro pokročilé – session tracking v MIDp aplikacích
Jak již z názvu článku vyplývá, budeme se zabývat implementací sledování sezení neboli session trackingem v MIDp aplikacích. Hlavním důvodem, proč tak musíme činit, je, že HTTP protokol je bezstavový. Tedy vždy, když klient vytvoří nový požadavek na server, jsou po jeho obsloužení jakékoli informace o něm ztraceny. Naštěstí existuje několik způsobů, jak na serveru identifikovat klienta. My si tu tentokrát ukážeme dva z nich.
Proč sledování sezení?
Chceme-li vytvořit jakoukoli aplikaci typu klient-server, ať už se jedná o multiplayer hru nebo například přístup do nějakého systému, je třeba udržovat informace o klientovi na serveru. Tímto způsobem jsme schopni klienta identifikovat a na základě jeho identifikace mu zasílat potřebná data, například změny ve hře.
Jak to funguje?
Základní princip spočívá ve vytvoření unikátního ID, které vygeneruje server při prvním požadavku a pošle jej zpět klientovi. Ten při každém dalším požadavku na server posílá i toto ID a server si tak o něm může udržovat informace. V tomto článku si ukážeme implementaci podobného mechanismu pomocí cookies a vlastního komunikačního protokolu.
Cookies
Tuto technologii vyvinula firma Netscape a postupem času se stala standardem pro všechny internetové prohlížeče. Cookies jsou malé textové informace ve formátu název_cookie=hodnota_cookie
a jsou součásti HTTP hlavičky. Jednotlivé cookie oddělujeme od sebe středníkem. Standardně jsou cookies uloženy v cache prohlížeče – v MIDp aplikacích se nabízí uložit přijaté cookies do RMS. Specifikaci a další informace naleznete v RFC2109 a RFC2695.
Serverová část
Základem serverové části je jednoduchý servlet, který si získává session z requestu
. Pokud se jedná o novou session, je do objektu response
uložena nová cookie s názvem session a hodnotou ID, získanou metodou getId
nad objektem session. Pro zpětnou kontrolu je vytvořen atribut counter
, který se při každém přístupu inkrementuje a jehož hodnota je pro kontrolu posílána zpět klientovi, který ji zobrazí.
HttpSession session = req.getSession(true); //získej session
if (session.isNew()) {
//přidej cookie
res.addCookie(new Cookie(„session“, session.getId()));
}
…
pw.println(„Counter = “ + counterStr); //pošli výsledek klientovi
Klientská část
V klientské části je nutné přečíst zaslanou cookie od serveru ze záhlaví „set-cookie“ HTTP protokolu (více v RFC2616). Protože žádnou jinou cookie server neposílá, obsahuje záhlaví řetězec session=xxx
, kde xxx je hodnota session. Tu musí klient vždy, když komunikuje se serverem, posílat zpět na server, o což se nám postará metoda setCookiesSession
. Její získání provede metoda getCookiesSession
, která iteruje přes všechny záhlaví protokolu, a najde-li záhlaví „set-cookie“, uloží hodnotu session do řetězce sessionIDStr
.
private void setCookiesSession(HttpConnection con) throws IOException {
con.setRequestProperty(„cookie“, sessionIDStr);
}
private void getCookiesSession(HttpConnection con)
throws IOException {
int headerIndex = 0;
while (con.getHeaderFieldKey(headerIndex) != null) {
String headerFieldKey = con.getHeaderFieldKey(headerIndex);
if (headerFieldKey.equals(„url-attachment“)) {
String value = con.getHeaderField(headerFieldKey);
sessionURLStr = „;jsessionid=“ + value.substring(value.indexOf(‚=‘) + 1, value.length());
}
headerIndex++;
}
}
Ve vlastní komunikaci jsou potom funkce použity následovně:
// získej connection
con = (HttpConnection) Connector.open(URL, Connector.READ, true);
//… nastavení záhlaví
if (sessionIDStr != null) {
setCookiesSession(con);
}
in = con.openInputStream();
// Před zpracováním dat získej cookie
if (sessionIDStr == null) {
getCookiesSession(con);
}
Proprietární komunikační protokol
Druhý způsob implementace používá k identifikaci klienta komunikační protokol, jehož součástí je i identifikační řetězec. Tento způsob má výhodu v tom, že identifikace je plně v naší režii a máme tak možnost plně ovlivnit datový typ identifikačního řetězce a optimalizovat náročnost na datový tok HTTP protokolu. Další změnou je nutnost implementovat správu sessions, tedy vytvoření, získaní dle ID a zrušení. Řešením může být objekt, který mimo vytvořené session ponese navíc informaci o čase vytvoření. Při každém požadavku je pak tento čas aktualizován. Pokud je časový rozdíl větší, než je nastavený timeout, session zrušíme.
Serverová část
Na rozdíl od předchozí metody je serverová část o něco složitější. Zasílá-li klient první požadavek na server, nemá k dispozici žádné ID, proto použije prázdný řetězec. Server takto identifikuje nového klienta, vytvoří pro něj novou session a uloží ji do cache pod klíčem, jenž session identifikuje. ID session zasílá zpět klientovi.
Vlastní implementace:
// vyžaduje klient novou session
boolean empty = ID.equals(„“);
if (empty) {
//získej novou session a ulož ji do cache
session = req.getSession(true);
sessions.put(session.getId(), session);
} else {
session = (HttpSession) sessions.get(ID);
}
//kód pro inkrementaci počítadla
//zapiš ID session a hodnotu počítadla
dos.writeUTF(session.getId());
dos.writeInt(counter);
dos.close();
os.write(baos.toByteArray()); //pošli výsledek klientovi
os.close();
Klientská část
Na straně klienta je třeba odezvu serveru zpracovat a získat session ID, které uložíme pro další požadavky zasílané serveru. Součástí odezvy je i aktuální hodnota počítadla, která v tomto případě slouží pouze pro kontrolu.
// získej outputstream a zapiš aktualní hodnotu ID
DataOutputStream dos = new DataOutputStream(con.openOutputStream());
dos.writeUTF((sessionProtocolStr != null)? sessionProtocolStr : „“);
//otevřeme inputstream a načteme ID session a počítadla
dis = new DataInputStream(con.openInputStream());
if (sessionProtocolStr.equals(„“)) {
sessionProtocolStr = dis.readUTF();
}
response = „Counter = “ + dis.readInt();
Ještě bych se chtěl zmínit o jedné věci. Jistě vás napadlo použít metodu pro přepis URL (URL rewriting). Tato metoda ovšem není použitelná, protože není způsob, jak dostat session ID ke klientovi. Pokud bychom použili některou z hlaviček HTTP protokolu, bylo by to v podstatě stejné jako použití cookies.
Kompletní zdrojové kódy našeho řešení jsou vám k dispozici.
Jakou metodu zvolit?
Jak vidíte, implementace sledování sezení v MIDp aplikacích je o něco komplikovanější a vyžaduje určité zásahy na straně klientské části, v případě implementace proprietárním protokolem i na serveru. Mimo tyto dvě metody je možné i zapouzdřit data do XML a použít XML wrapper, ovšem vzhledem k náročnosti na přenos dat není tato metoda zrovna nejvhodnější.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Fandíme českým sportovcům a rozdáváme hosting ZDARMA!
26. července 2024 -
Rychlost serveru: Klíč k lepšímu umístění ve vyhledávačích
7. června 2024 -
Jak zabezpečit váš chytrý telefon před kybernetickými hrozbami
30. listopadu 2023
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024