Vorgurakendused 2 prax 1 2012: erinevus redaktsioonide vahel
| 57. rida: | 57. rida: | ||
post call urlile | post call urlile | ||
<pre> | <pre> | ||
http://11.22.33.44:2345/foundfile | http://11.22.33.44:2345/foundfile | ||
<pre> | </pre> | ||
kus post päringu sisu (peale headeris olevat tühikut) on | kus post päringu sisu (peale headeris olevat tühikut) on | ||
json formaadis list failide täisnimedega a la | json formaadis list failide täisnimedega a la | ||
Redaktsioon: 2. september 2013, kell 17:45
Sisuliselt sama ülesanne väikeste nüansivahedega on olemas 2010 ja 2011 aasta arhiivis. arhiivis
Ülesandeks on ehitada P2P rakendus nimega [wazaa] failide otsimiseks võõrastest masinatest, mis leiab teisi kasutajaid ise tehtud P2P mehhanismi abil.
Kasutajaliidese hea kvaliteet ei ole praksis oluline.
Üldkirjeldus
Wazaa võimaldab:
- kasutajal otsida võõrastest masinatest faile failinimes sisalduva stringi (näiteks "Film1") järgi.
- Seejuures otsitakse ainult wazaa kataloogis olevaid faile, mitte ei otsita kogu masinat läbi. wazaa kataloogis ei ole alamkatalooge.
- Leitud failid kuvatakse loetelus, kus on võõra masina IP, port ja terviklik failinimi.
- kasutajal tõmmata endale faili kuvatud loetelust, teades masina IP-d, porti ja failinime.
Failide leidmiseks kasutab wazaa järgmist viisi:
- Saadab tema oma masinas oleva faili machines.txt masinatele failiotsingu päringu. machines.txt sees on masinate ip ja pordid json listina kujul
[["11.22.33.44","2345"],...,["111.222.333.444","23456"]]
- Samamoodi saadab failiotsingu-päringu wazaa startlehel http://dijkstra.cs.ttu.ee/~tammet/wazaa.txt olevatele masinatele (startlehel on plaintekstina eelmises punktis näidatud formaadis json-fail)
- Kui mingi masin leiab minu otsitud faili, siis ta saadab mulle teate, et mis IP ja pordiga masin ja mis täisnimega fail on.
Ehk, masinad saadavad minu antud päringut rekursiivselt ise edasi.
Tehnilised nõuded
Programmeerimiskeele ja muu tehnoloogia valik on vaba, kuid rakendus peab vastama neile tingimustele:
- Kogu programm peab töötama kas AK klassi arvutis või teie oma läptopis, mis AK klassis kaasas. Mingit kaugel asuvat serverit põhirakenduse jaoks kasutada ei tohi.
- Http protokolli jms realisatsioon peab olema teie oma programmi osa, mingit "suurt" http serverit a la apache kasutada ei või.
Protokoll
Konkreetselt masinalt 11.22.33.44 kus wazaa jookseb pordis 2345 sobivate failide pärimine:
http://11.22.33.44:2345/searchfile?name=filename&sendip=55.66.77.88&sendport=6788&ttl=5&id=wqeqwe23&noask=11.22.33.44_111.222.333.444 ...
kus parameetritel on järgmine sisu:
- name: otsitav string (peab olema failinimes)
- sendip: esialgse otsija ip
- sendport: esialgse otsija port
- ttl: kui mitu otsingu-hopi veel teha (iga edasiküsimine vähendab ühe võrra)
- id: optsionaalne päringu identifikaator
- noask: optsionaalne list masinatest, kellelt pole mõtet küsida (eraldajaks alakriips)
Leitud failist teadaandmine:
post call urlile
http://11.22.33.44:2345/foundfile
kus post päringu sisu (peale headeris olevat tühikut) on json formaadis list failide täisnimedega a la
{ "id": "wqeqwe23",
"files":
[
{"ip":"11.22.33.66", "port":"5678", "name":"minufail1.txt"},
...
{"ip":"11.22.33.68", "port":"5678", "name":"xxfail1yy.txt"}
]
}
kus elementidel on järgmine sisu:
- id: esialgse päringu id
- name: täispikk leitud faili nimi
- ip: masina ip, kus antud fail asub
- port: masina wazaa port, kus antud fail asub
Konkreetselt masinalt 11.22.33.44 kus wazaa jookseb pordis 2345 konkreetse faili pärimine:
http://11.22.33.44:2345/getfile?fullname=fullfilename
Viimasele, getfile päringule vastatakse faili saatmisega üle http protokolli (st headeris on kindlasti ka content-length ja mime type).
==
- alustuseks suutma leida üles teise kasutaja (nime järgi, näiteks "jaanus") masina
ja võtma ühendust selles masinas oleva chatirakendusega. Selleks on vaja nime järgi teada saada ip ja port. Kui ühendus on saadud, peab töötama chat: mingeid kellasid ja vilesid chati jaoks (näod, värvid vms vms) ei ole praksi jaoks vaja teha.
Nimede seost ip ja pordiga hoitakse iga rakenduse masinas eraldi failis, mingit keskset serverit ei ole. Rakendused jagavad neid faile omavahel ja täiendavad oma faili teistelt saadud infoga.
Vaata ka väikest näitestsenaariumi.
Esimese kasutamise korral tuleb oma nimi registreerida ja rakendus peab kontrollima, et see nimi ei oleks kellegi poolt juba kasutusel.
Rakendus peab ühenduma teiste rakendustega hariliku http protokolli kaudu, allpool on toodud detailid.
Programmeerimiskeele ja muu tehnoloogia valik on vaba, kuid rakendus peab vastama neile tingimustele:
- Kogu programm peab töötama kas AK klassi arvutis või teie oma läptopis, mis AK klassis kaasas. Mingit kaugel asuvat serverit põhirakenduse jaoks kasutada ei tohi.
- Http protokolli jms realisatsioon peab olema teie oma programmi osa, mingit "suurt" http serverit a la apache kasutada ei või.
Praksi kaks osa
Väga soovitav on teha praks kahes osas ja esitada kaks korda ülevaatamiseks:
- Teha http protokolli järgida suutev esmane rakendus.
- Lisada sinna kogu vajalik funktsionaalsus.
Http protokolli järgimise võimet kontrollitakse praksi eduka läbimise tingimusena.
Soovitusi ja ideid
Chatiprogramm peab päris kindlasti sisaldama või kasutama http serverit, muidu ei ole temaga võimalik väljast ühendust võtta. NB! See ei tähenda mingit nö suurt veebiserverit a la apache, vaid pigem ise kirjutatud väikest minimaalset serverit, mis pealegi ei pea veebilehti serveerima ja cgi-sid käivitama, vaid ainult teatud käskudele/parameetritele reageerima.
Server tuleb realiseerida ise, kasutades võrgust leitavaid näiteid mikro-http-serveri jaoks (tüüpiliselt paar lehekülge koodi). Selliseid näitekoode võib täiesti otse kasutada.
C jaoks on sobiv mikroserver näiteks tiny, java jaoks on see server väga hea väike näide, aga selgitava tekstita, ning selgitavate tekstidega servereid leiad mh siit ja siit.Loe java socketitest põhjalikumalt siit. Pythoni serverinäite saad siit. Http kohta võib lugeda näiteks siit.
Kasutajaliides võib olla tehtud aknaga nagu chat enamasti on, aga see ei ole kohustuslik: võib teha ka puhtalt käsurea rakenduse, mille kutsud välja oma ja otsitava nimega (või uue nime tegemise käsuga) ja mis küsib siis käsurealt järjest sinu teksti ja trükib teise tekste välja. Selline rakendus peab siis ikkagi suutma järjest lugeda sinu kirjutatut ja järjest trükkima saadud tekste, st interaktiivsus on kindlasti vajalik.
Rakendus on mõistlik teha nii, et annad käivitamisel ette pordi, millel ta räägib ja oma nime: selliselt saad ühte masinasse kergesti käima panna erinevaid chatte ja siis ühe masin piires debugida. Arusaadavalt peaks siis andmefail olema ka iga chati jaoks erinev: kas fail sisaldab pordi nime või antakse tema nimi samuti ette. Muidugi oleks kena teha nii, et kui neid parameetreid käivitamisel ette ei anna, siis kasutab ta vaikeväärtusi.
Häid selgeid näiteid ja õpetusi socketite ja serveri tegemise kohta leiad veel siit:
- socketite kasutamise õpetus ja source C-s, javas ja pythonis
- lihtne veebiserver C-s (eksootilise sanosi all)
- lihtne veebiserver/klient C-s (ibm-i tutorial ja source)
- tiny webserver C-s
- java socketid: klassikaline tutorial
- Kaarel Alliku kursuse näite-jutukas (java)
- java http teegi kasutamine, mis kasutab socketeid sisemiselt
- ruby
- python
- pythoni üks serversocketi-teek
- Väga põhjalik socketite/võrguprogrammeerimise õpetus
Firewall ja NAT
Firewallist läbi murdmise ja kinniste portidega ühendamise probleemiga ei pea selles praksis tegelema. Samas tähendab see, et ei ole kuigi lihtne teise masinaga tegelikult ühendust saada (ühes masinas debugimise võimaldamine ongi seepärast kriitiline).
Kes chati käima saab, võib mõelda välja ja realiseerida probleemi lahendamiseks sobiva vaheserveri: selle eest saab ekstrapunkte.
Võrgust infot otsides leiad kahte liiki teemasid, meie jaoks oluline on siit listist teine:
- Tunneldamise artiklid, loe näiteks http tunnel artiklit wikipediast ja seda artiklit firewallist läbipääsemisest.
- UDP/TCP hole punching ja NAT traversal: arusaadava sissejuhatusena loe Skype jms süsteemide meetoditest, sellele väike täiendus. Vaata ka wikipedia utiliitide artiklit ja viiteid. Detailsemalt/lisaks siit ja siit ja siit ja siit, keerulise vahendi leiab siit
NB! Seda kõike ei ole väga lihtne teha ja sinu chatiklient (ja ka selle inimese chatiklient, kellega suhtled) peab ka oskama seda vaheserverit kasutada. Ära hakka seda ehitama, kui nö lihtne chat veel ei tööta!
Ekstra-lisapunktide saamise variant: realiseeri ja pane kõigile kasutatavaks firewalliprobleemi lahendamiseks sobiv vaheserver. Kirjuta kasutamise juhend ja näited, mida teised saaks soovi korral oma chatiproge jaoks tarvitada (st panna nad sinu vaheserverit kasutama, nii et seda saaks ka arvutiklassist kasutada). Esimesed kaks gruppi, kes sellega hakkama saavad, saavad lisaks pooled praksipunktid!
Punktiarvestusest
Kui kõik eelnimetatu töötab vastu mõne teise grupi chatiprogrammi ja koodi suudetakse seletada, saab täispunktid.
Kui teiste chatiprogrammidega eriti ei suuda suhelda, aga iseenda koopiatega siiski, saab miinuspunkte.
Oma lisa-asjade ehitamise ja töötamise demo korral (mitme kasutaja chat vms) saab täispunktidele lisaks lisapunkte.
Detailid: mis info peab rakendusel olema ja kuidas tegutseb
- mul omal on fail nimi/ip_pluss_port paaridega järgmise json süntaksiga (palun realiseerida täpselt nii, st eraldi klambri-read alguses ja lõpus ja ei mingeid tühikuid väljapool isikunime ja eeldusega, et nimes pole jutumärke: siis saab seda faili kergesti parsida ja muuta ka ilma spetsiaalselt json-parserit kasutamata).
[ ["Tanel Tammet","22.33.44.55:6666"], ["Peeter Laud","22.33.44.11:6666"] ]
- pean saama registreerida oma nime (ühekordne): minu masin saadab minu nime ja ip igalepoole ja need saadavad edasi ja need saadavad jälle edasi ja kui keegi leiab et on, siis saadab mulle teate, et juba hõivatud
- login sisse, annan oma nime
- minu rakendus saadab kõigile/osale teada ip-dele minu nime ja pika id ip ja nemad updatevad oma tabeli
- pean leidma kasutaja, kellega tahan suhelda, ip ja pordi. Tulemus oleks (vähemalt) tema ip teadasaamine.
- kirjutan nime.
- omal on mul fail nimi/ip paaridega. Kui sealt leian, ok.
- kui ei, küsin teiste masinatest nende faile, kasutades minu failis olevaid ip-sid. Nemad lihtsalt saadavad oma faili.
- kui ma leian tabelist nime, korras, katkestan
- kui ma lõpuks ei leia, siis kaks varianti:
- otsin ise uuelt ringilt ip-delt, mis sain (see peab töötama)
- saadan kõigile oma faili ip-dele info, et nemad otsiks mulle (kui see realiseerida ja katsetada, saab veidi lisapunkte)
- pean saama leitud id ja pordiga chatiprogrammile oma teksti saata ja tema teksti kuvada
Detailid: millist protokolli ja eeldusi rakendus kasutab
Algul vaikimisi port on 6666, kuid see peab olema suhteliselt kergelt muudetav (ümberkompileerimine on ok, aga soovitav on käivitada chat koos käsurealt antava pordiga).
Ip esitatakse alati koos pordiga.
Time to live (TTL) on number, mida päringu edasisaatmise juures tuleks vähendada ja null TTL-ga päringut ignoreerida, kui tegu info edasisaatmisega. Enamuse päringute juurs võib seda ignoreerida, ta on protokollis juhuks, kui soovida realiseerida lisaks edasisaatmist.
- Nime olemasolu küsimine on asünkroonne: esitad päringu ja kunagi hiljem saadetakse sulle vastus tagasi.
http://11.22.33.44:PORT/chat/findname?name=NIMI&myip=22.22.33.44:6666&ttl=TIMETOLIVE
Vastust ignoreeritakse! Päringu saaja peaks nime leidmise korral (mitte muidu!) omakorda saatma vastuspäringu (seda siis arvestatakse):
- Vastuse saatmine nime küsimisele:
http://11.22.33.44:PORT/chat/sendname?name=NIMI&ip=22.22.33.44:6666&ttl=TIMETOLIVE
Sisu ignoreeritakse! Saadud päring tähistab lihtsalt, et nimi on leitud selle ip-ga.
- Minu nime/ip teatamine on sama kui eelmine päring, näiteks
http://11.22.33.44:PORT/chat/sendname?name=NIMI&ip=22.22.33.44:6666&ttl=TIMETOLIVE
- Nimed/ip_pluss_port faili küsimine on sünkroonne, st vastus tuleb otse päringuvastusena:
http://11.22.33.44:PORT/chat/asknames?ttl=TIMETOLIVE
Vastuseks antakse fail ise, json formaadis:
[ ["Tanel Tammet","22.33.44.55:6666"], ["Peeter Laud","22.33.44.11:6666"] ]
- Chatisõnumi saatmine
http://11.22.33.44:PORT/chat/sendmessage?myname=tanel&myip=22.33.44.55:6666&message=asasas&ttl=TIMETOLIVE