HTML render engine

Nem hittem volna, hogy valaha eljutok oda, hogy html alkalmazások esetén is render enginet, és renderereket fogok írni. A webes világ most ért el oda, ahol a pc-s már egy ideje tart, és várhatóan az emberek többsége most szembesül majd azokkal a problémákkal (lehet picit később) amikkel a „pc”-s fejlesztők már évek óta.
Annyi a különbség, hogy itt nem D3d-nek, vagy opengl-nek hívják a dolgokat, de ez az idő sincs már messze.
Tehát ha valaki webes alkalmazást fejleszt, és számít neki a sebesség, esetleg nem akarja kéthavonta újraírni az alkalmazását, az alábbi desgin patternt kövesse (hacsak nem akar pórul járni):

Renderer’s (software -> html dom, hardware -> html5 canvas, bármi más)
Render Engine
Game Logic
Game Data
Game Assets

Így talán van esélye, hogy ha 180 fokos fordulatot vesz a világ akkor se kelljen kidobni többéves munkáját.

Egy ötletes kis demóval zárom a mai napot: http://gwtcanvasdemo.appspot.com/

Youtube HD

Youtube-on már egy ideje elérhetőek a HD felbontású videók, de akárhányszor elkezdtem nézni egyet, valamiért mindig akadt. Annyira nem voltak érdekesek, hogy megvárjam a fél vagy egy óra pre-buffert, de hát azért mégiscsak. Gondoltam ez itt a kelet, nincsenek szerverek, sávszélesség, megfelelő adottságok.

Picit alaposabban megvizsgálva a dolgot szembetűnő, hogy a google szervereivel nincs baj, szépen lehet róluk tölteni direktbe 1-2 M/s-el… Akkor mi a probléma? Az adobe flash, mi más.

Valaki azt gondolta, 100k kb/s mindenre elég lesz, miért is akarna valaki ennél több adatot letölteni egyszerre? Ez különösen nagyszerű döntés mindenkinek aki széles sávon ül. 100k-ra tördelt csomagokkal lehet a leginkább elérni a régi analóg modemek szintjét 120Mbps-es vonalakon.

A megoldás ezek után már “triviális”:
El kell menni az adobe oldalára (egy flash-t beállító html oldalra…):
http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager03.html

és addig ügyeskedni, amíg az alábbi kép nem tárul elénk:

(Akinek nem sikerül: a csúszkát kell addig jobbra húzni, amíg a szöveg Unlimited-re vált… 🙂 )

A beállítás után gyorsabban betöltődik a 720p-s videó, mint a sima előtte.

Magyar karakterek irssi alatt

Bizonyos linux-okon az irssi alatt furcsán viselkednek az ékezetes karakterek. A megváltást itt is (általában ilyen esetekben mindig) az UTF-8 jelenti.

Az alábbi 2 beállítást kell tenni:
A putty-ban be kell állítani, hogy UTF-8-at használjon:
Putty Configuration: Window - Translation - Recieved data assumed to be in which character set: UTF-8

Irssi alatt:


Q: How to make UTF-8 support work with irssi?

A: Make sure your terminal supports UTF-8 (for example, xterm -u8). If you use screen, you may have to do screen -U. And in Irssi do /SET term_charset utf-8. (for 0.8.9 and older: /SET term_type utf-8)

(forrás: http://irssi.org/documentation/faq)

Ezek után irssi-be érdemes még mondani egy /save és kész is vagyunk…

Facebook

Ma halottam az érdekes hírt, hogy a facebook állítólag OP-olta a Google-t. Gyorsan én is regisztráltam, lássam mi a trükk. Nagyából látom, csináltak egy egyszerűen használható, ergonomikus honlapot. A vizsgálódás közben nem tudtam megállni, hogy ne cseréljek fel pár betűt az egyik oldalon. Szerintem így még jobb lenne. Ha majd ilyet is tud, akkor szerintem mindenki regisztrálni fog 😉

Lájkolja mindenki aki szereti 😉

GWT rpc servlet Vs Apache proxy

A gwt alkalmazások (egyik) legnagyobb előnye a perfect cache kezelés. Ahhoz, hogy ez hatékony legyen érdemes minden statikus tartalmat egy apache-ra rakni, és csak az RPC hívásokat átfűzni egy proxy-n az alkalmazás szerver felé. Ennek hatására viszont előállhat az a furcsa helyzet, hogy az RPC szolgáltatásokat kezelő szervlet context-root-ja eltér a statikus fájlok context-root-jától.

Ezt a GWT rpc kezelő servlete nem szereti valami nagyon és mindenkit megjutalmaz az alábbi hibaüzenettel:

[10/28/10 12:50:44:383 CEST] 00000041 webapp        I com.ibm.ws.webcontainer.webapp.WebApp log SRVE0296E: [app_war#app.war][/app/services][Servlet.LOG]:.PartnerServiceServlet: ERROR: The module path requested, /app/, is not in the same web application as this servlet, /app/services.  Your module may not be properly configured or your client and server code maybe out of date.:.null

Ez önmagában nem baj, csak csúnya, de amikor komplex osztályokat küldünk fel a szerverre, ennél komolyabb hibák is jelentkeznek (cannot load serialization policy).

Ennek oka, hogy az RPC üzenetek hordozzák magukban, hol keletkeztek, és a szerver oldal ellenőrzi, hogy az egyezik e a context rootjával.

Ha megfigyeljük az RPC hívások tartalmát látszik, hogy az url a verziók után utazik, pl:

verziók|hívó|ser policy fájl|hívás névtér|szolgáltatás, stb…

A valóságban valami ilyesmi:

5|0|9|http://server/app/|D0C8380096848CC179C5488360839537|hu.aftershock.client.services.gwtrpc.modules.common.ICommonService|getCommonCodes

A probléma a 4 résznél van, amit cserélni kell (ha az alkalmazás context rootja nem /app hanem /app/services). Ezt oly módon tudjuk megtenni, hogy leszármazunk a RemoteServiceServlet osztályból, és felülírjuk a processcall funkciót (ezt egyébként is érdemes megtenni, ide lehet mindenféle hasznos dolgot mint profiling, audit, security implementálni).

@Override

public String processCall(String paydload) throws SerializationException {

paydload=mainUrlFix(paydload);

A mainUrlFix implementáció az alábbi módon néz ki:

private String mainUrlFix(String payload) {

int tokenNum=0;

String prefixString=””, mainUrl=””, postfixString=””;

for (int i=0, il=payload.length(); i<il; i++ ) {

if (payload.charAt(i)== AbstractSerializationStream.RPC_SEPARATOR_CHAR) {

tokenNum++;

if (tokenNum==3) {

prefixString=payload.substring(0,i);

} else if (tokenNum==4) {

mainUrl=payload.substring(prefixString.length(),i);

postfixString=payload.substring(i);

break;

}

}

}

if (!mainUrl.endsWith(“services/”)) {

mainUrl+=”services/”;

}

return prefixString+mainUrl+postfixString;

}

UPC internet féláron

Nem kell sokat a sorok között olvasni, hogy a UPC felsővezetése egyáltalán nem a partnerek elégedettségére hajt. Biztos vagyok benne, hogy minden vezetői értekezleten egy számot tartalmazó report képezi a board elégedettségének alapját, ami az új ügyfelek számát tartalmazza.

Ezért aki már nem új ügyfél, könnyen ráfizet. Vegyük alapul a mostani akciót. A legdrágább előfizetés 6000 forint. Aki már 3 éve előfizető ugyanezért 12000 forintot fizet.

Felmerülhet az ötlet mindenkiben, minek fizessek 2x annyit, lemondom, és újrakötöm. Sajnos erre gondoltak, ha valaki lemondja az előfizetését, akkor a lemondás címére (igen nem név, és nem előfizető hanem cím) 3 hónapig nem köthet akciós szolgáltatást. Ez különösen jó dolog akkor, ha valaki kiköltözik valahonnan, jól ki tud tolni az utána jövővel.

Ellenben van megoldás. Első körben szerezni kell egy címet, ahol nem neteznek, de elérhető a UPC. Át kell köttetni oda az internet előfizetést (ez ingyenes). Le kell mondani az internet előfizetést (átköltözetni és lemondani többször is lehet). Újra kell kötni az internet előfizetést. Lehet örülni a félárú internetnek. A legjobb a dologban, hogy lemondott címre 3 hónapig nem lehet kötni kedvezményes előfizetést, de már meglévőt átköttetni lehet.

Online Youtube to mp3 converter

A youtube-on található zenék hangminősége elég kérdéses, de ha valaki csak azért halgat meg egy zenét, hogy megtanulja (tehát a hangminőség nem releváns), arra bőven elég. Sajnos a youtube sok dolgot viszont nem tud, ezért szükségünk lehet a hanganyagra valami “fogyasztható” videó nélküli formátumban. Erre az általam ismert legjobb megoldás:

http://www.dirpy.com/

Online, gyors, és mindent tud, amire csak szüksége lehet az embernek egy ilyen konvertálás során.

Levélküldés tesztelése

Manapság már nem nagy dolog olyan alkalmazást fejleszteni ami emailt tud küldeni. Ellenben fejlesztés alatt egyáltalán nem biztos, hogy szerencsés, ha a valódi felhasználók a fejlesztők viccesebbnél viccesebb tárgyú leveleit kapják kézhez (pl. szerződését díjrendezettség hiányában töröltük, stb). Ezt elkerülendő lehet mindenféle if-eket írni a kódba, de ez sajnos megváltoztatja a program működését, és ezzel a metódussal elég sok potenciális hibaforrást elrejthetünk a kódban. Célszerűbb csinálni egy saját smtp szervert, ami e leveleket fogadja, de nem küldi ki, hanem lementi egy könyvtárba.

Erre a legegyszerűbb megoldás linux alatt a fakemail nevű program, ami a phytonnal együtt jön.

Tehát a telepítés

sudo apt-get install python

Az indítás (pl. init.d-ből)

sudo su -c ‘fakemail.py –host=voji.hu –port=10025 –path=/var/samba/servers/smtp –background’ voji

A lényeg a ‘ ‘ jelek közötti rész, a su -c csak azért felel, hogy voji userként fusson a szerver.

A paraméterek:

  • host – a cím, ahol a szerver fut
  • port – port ahol hallgatózik majd az smtp szerverünk
  • path – könyvtár ahova a leveleket lementi amit a szerveren keresztül küldenek.
  • background – háttérben fusson, ne a konzolon

Mindenkinek saját dns szervert

Amennyiben az otthoni számítógépünk nem rendelkezik fix ip-címmel, sokat segíthet a DynDNS szolgáltatás. Ennek segítségével beregisztrálhatunk magunknak egy tetszőleges domain nevet (ingyen) és a szolgáltatáshoz adott kis kliens program segítségével (linux alatt ddclient apt-get-tel telepíthető) az otthoni gépünk mindig frissítheti a saját dns-éhez tartozó ip címét (tehát akkor is elérhetjük a gépünket, ha a gonosz szolgáltató más ip-t adott neki).

Tegyük fel, adott Lajos, aki szeretné a számítógépét elérni otthonról. Beregisztrálja magának a lajos.homeip.net címet. Ezek után az otthoni számítógépét mindig eléri ezen a címen, aminek nagyon örül. Ellenben ha Lajos belső hálózatot is használ, akkor két dolgot tapasztalhat:

1. Olyan szerencsés, hogy a routere támogatja a nat loopback funkciót, és ha beírja otthon, hogy lajos.homeip.net akkor minden működik

2. Nem szerencsés

A nem szerencsés esetet két féle képpen orvosolhatjuk. Ha beírjuk a hostfile-ba, hogy lajos.homeip.net az a szerver lokális ip címe (pl 192.168.2.1). Ez jó, de ha Lajos hazamegy, midnig át kell írnia a host-fájlt, ha meg elmegy otthonról midnig vissza kell írni. Lássuk be ez nem a legelegánsabb megoldás.

Másik alternatíva, hogy Lajos saját dns szervert csinál. Ez azért is hasznos, mert megismeri a DNS szerverek működését, és felépítését (persze csak nagyon felületesen) és mert lát ilyet is…

Linux alatt dns szerverre a bind nevű csomagot szokták használni, amit az alábbi módon telepíthetünk:

sudo apt-get install bind9

Ezekután már van jól működő DNS szerverünk, ami a 67-68 udp portokon üzemel már csak konfigurálni kell. A dns szerver konfigurációját az alábbi helyen találjuk: /etc/bind

Ide kell két fájlt létrehoznunk, ami alapján a dns szerver megoldja majd a név-ip és ip-név fordítást.
db.1.168.192
;
$TTL 604800
@ IN SOA localhost. lajos.homeip.net. (
28 ; Serial
604800 ; Refresh
86400 ; Retry
241920 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS localhost.
2 IN PTR lajos.homeip.net.

db.homeip.net
;
$TTL 604800
@ IN SOA homeip.net. lajos.homeip.net. (
28 ; Serial
604800 ; Refresh
86400 ; Retry
241920 ; Expire
604800 ) ; Negative Cache TTL
;

@ IN NS dns1.hu.
@ IN NS dns2.hu.

@ IN A 204.13.248.119
www IN A 204.13.248.119
lajos IN A 192.168.1.2

Az db.1.168.192 nevű fájl megmondja, hogy a 192.168.1 tartományban a 2 ip cím (192.168.1.2) az nem más mint a lajos.homeip.net.

A második db.homeip.net nevű fájl pedig megmondja, hogy a homeip.net domainban a sima hivatkozás nemmás mint a homeip.net szerver neve (ezt ping homeip.net-el meg lehet tudni), és a lajos.homeip.net pedig nemmás mint a 192.168.1.2 ami a szerverünk címe…

Ezek után már csak használni kell ezeket a fájlokat, a named.conf.local fájlba fel kell venni az alábbi két sort:

include “/etc/bind/zones.rfc1918”;

zone “1.168.192.in-addr.arpa” {
type master;
file “/etc/bind/db.1.168.192”;
};

zone “homeip.net” {
type master;
file “/etc/bind/db.homeip.net”;
};

Ezek után kell egy bind újraindítás (/etc/init.d/bind9 restart), ha elrontottunk valamit arról a var/log/syslog-ban fogunk kapni infót.

Az eredményről magunk is meggyőződhetünk:

dig @localhost lajos.homeip.net

Értelemszerűen a dhcp szervernek meg kell adni, hogy a DNS szerver címe a lokális szerver (192.168.1.2) legyen.