Web-palvelimen toiminta
Tässä luvussa tarkastellaan web-palvelinten ja selainten toimintaa. Palvelimet noudattavat tyypillisesti asiakas-palvelin -mallia, ja web-palvelimet ja selaimet keskustelevat HTTP-protokollaa noudattaen. Tämän lisäksi tarkastellaan Javan tarjoamia välineitä palvelinyhteyden muodostamiseen sekä palvelimen toteuttamiseen.
Asiakas-palvelin malli
Asiakas-palvelin -mallissa (Client-Server model) asiakkaat käyttävät palvelimen tarjoamia palveluja. Kommunikointi asiakkaan ja palvelimen välillä tapahtuu usein verkon yli siten, että selain ja palvelin sijaitsevat erillisissä fyysisissä sijainneissa (eri tietokoneilla). Palvelin tarjoaa yhden tai useamman palvelun, joita käyttäjä käyttää selaimen kautta.
Käytännössä selain näyttää käyttöliittymän ohjelmiston käyttäjälle. Selaimen käyttäjän ei tarvitse tietää, että kaikki käytetty tieto ei ole hänen koneella. Käyttäjän tehdessä toiminnon selain pyytää tarpeen vaatiessa palvelimelta käyttäjän tarpeeseen liittyvää lisätietoa. Tyypillistä mallille on se, että palvelin tarjoaa vain asiakkaan pyytämät tiedot ja liikkuvan tiedon määrä pidetään vähäisenä.
Asiakas-palvelin -malli mahdollistaa hajautetut ohjelmistot: selainta käyttävät loppukäyttäjät voivat sijaita eri puolilla maapalloa palvelimen sijaitessa tietyssä paikassa.
:
Log in to view the quiz
Yhteyden muodostaminen palvelimelle Java-maailmassa
Ohjelmoijan näkökulmasta porttia voi ajatella tiedostona. Tiedostoon voi kirjoittaa ja siellä olevaa tietoa voi lukea. Kirjoitettava ja luettava tieto ei kuitenkaan toiseen koneeseen yhteyttä ottaessa tule tiedostosta, vaan yhteyden toisessa päässä toimivasta ohjelmasta. Tarkastellaan seuraavaksi yhteyden muodostamista palvelimelle Java-kielellä.
String osoite = "www.helsinki.fi";
int portti = 80;
// muodosta yhteys
Socket socket = new Socket(osoite, portti);
// lähetä viesti palvelimelle
PrintWriter kirjoittaja = new PrintWriter(socket.getOutputStream());
kirjoittaja.println("GET / HTTP/1.1");
kirjoittaja.println("Host: " + osoite);
kirjoittaja.println();
kirjoittaja.flush();
// lue vastaus palvelimelta
Scanner lukija = new Scanner(socket.getInputStream());
while (lukija.hasNextLine()) {
System.out.println(lukija.nextLine());
}
Yllä oleva ohjelma ottaa yhteyden etsii www.helsinki.fi -osoitteeseen liittyvän palvelimen, ottaa yhteyden palvelimen porttiin 80, ja lähettää palvelimelle seuraavan viestin:
GET / HTTP/1.1 Host: www.helsinki.fi
Tämän jälkeen ohjelma tulostaa palvelimelta saatavan vastauksen.
Palvelimen toiminta Java-kielellä
Tarkastellaan seuraavaksi palvelimen toimintaa Java-kielellä.
Web-palvelin lukee tyypillisesti ensin pyynnön, jonka jälkeen pyyntöön kirjoitetaan vastaus. Alla on esimerkki yksinkertaisen palvelimen toiminnasta — palvelin on toiminnassa vain yhden pyynnön ajan.
// odotetaan pyyntöä porttiin 8080
ServerSocket server = new ServerSocket(8080);
Socket socket = server.accept();
// luetaan pyyntö
Scanner lukija = new Scanner(socket.getInputStream());
// ...
// kirjoitetaan vastaus
PrintWriter kirjoittaja = new PrintWriter(socket.getOutputStream());
// ...
// suljetaan resurssit
lukija.close();
kirjoittaja.close();
socket.close();
server.close();
ServerSocket
-olion accept
-metodi on blokkaava. Tämä tarkoittaa sitä, että accept
-metodia kutsuttaessa ohjelman suoritus jää odottamaan kunnes palvelimeen otetaan yhteys. Kun yhteys on muodostettu, accept
-metodi palauttaa Socket
-olion, jota käytetään palvelimen ja yhteyden ottaneen koneen väliseen kommunikointiin.
Kokeile ylläolevaa ohjelmaa omalla koneellasi. Ohjelma käynnistää palvelimen, joka kuuntelee pyyntöä paikallisen koneen porttiin 8080
. Voit tehdä HTTP-muotoisen pyynnön porttiin 8080 selaimella kirjoittamalla selaimeen osoitteeksi http://localhost:8080
.
Palvelin halutaan tyypillisesti toteuttaa niin, että se kuuntelee ja käsittelee pyyntöjä jatkuvasti. Tämä onnistuu toistolauseen avulla.
// luodaan palvelin porttiin 8080
ServerSocket server = new ServerSocket(8080);
while (true) {
// odotetaan pyyntöä
Socket socket = server.accept();
// luetaan pyyntö
Scanner lukija = new Scanner(socket.getInputStream());
// ...
// kirjoitetaan vastaus
PrintWriter kirjoittaja = new PrintWriter(socket.getOutputStream());
// ...
// vapautetaan resurssit
lukija.close();
kirjoittaja.close();
socket.close();
}
Kun käytössämme on valmiit selaimet ja palvelimet, voimme keskittyä web-sovelluksen logiikan toteuttamiseen.