O projekcie

Projekt składa się z czterech plików: hotel.js, hotel.html, client/client.js oraz lib/reservations.json.

hotel.js jest skryptem po stronie serwera. Odpala się on poleceniem


node hotel.js

Zadaniem tego skryptu jest utworzenie serwera HTTP i opracowanie zapytań od klienta. Serwer jest uruchomiony na porcie 8080, system jest dostępny po adresie http://localhost:8080


let server=http.createServer(hotel)

// Listen on port 8080, IP defaults to 127.0.0.1
server.listen(8080);

// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8080/");

hotel jest funkcją, w której ustala się, w jaki sposób opracowuje się zapytania klienta

let hotel=function (request, response) {
   // Parse the request for arguments and store them in get variable.
   // This function parses the url from request and returns object representation.
   let get = url.parse(request.url, true).query;
   if(request.url=='/hotel.js'){
      notFound(response);
   }
   else if(request.url=='/' || request.url=='/hotel.html'){
      fs.readFile('hotel.html', 'utf-8', getReadFile(response,'text/html'));
   }
   else if(request.url.substr(-3)=='.js'){
      fs.readFile('.'+request.url, 'utf-8', getReadFile(response,'application/javascript'));
   }
   else if(get['data']=='calendar'){
      response.writeHead(200, {'Content-Type': 'text/plain'});
      response.end(getCalendar(get['year'],get['month'],get['day']));
   }
   else if(get['data']=='rooms'){
      response.writeHead(200, {'Content-Type': 'text/plain'});
      response.end(getRooms(get['year'],get['month'],get['day']));
   }
   else if(get['data']=='book'){
      response.writeHead(200, {'Content-Type': 'text/plain'});
      response.end(bookRoom(get['room'],get['year'],get['month'],get['day']));
   }
   else{
      notFound(response);
   }
}

Przykładowo, jeżeli URI w zapytaniu to / lub /hotel.html, to serwowany zostanie plik hotel.html z typem MIME text/html. Jeżeli URI kończy się przez .js, to zostanie serwowany odpowiedni plik z typem MIME application/javascript (za wyjątkiem pliku hotel.js).

Pozostałe zapytania opracowuje się w zależności od parametru data zapytania. Na przykład, w odpowiedzi na zapytanie z URI /?data=calendar&year=2013&month=5&day=23 zostanie serwowany z typem MIME text/plain wynik funkcji getCalendar(2013,5,23). Zwróć uwagę na to, że miesiące ja numeruję od zera. 5 — to jest czerwiec.

Plik hotel.html zawiera kod HTML.

<!DOCTYPE HTML>
<html>
  <head>
    <title>Rezerwacja noclegów w motelu “Overlook”</title>
    <meta charset="utf-8">
    <script src="client/client.js"></script>
</head>
<body>
<header>
  <h1>Rezerwacja noclegów w motelu “Overlook”</h1>
</header>
<ahead id='calendar'></ahead>
<article>
  <h1><time id='dat'>Data</time></h1>
  <ul id='rooms'>Rooms</ul>
</article>
</body>
</html>

Zawiera on trzy pojemniki: <ahead id='calendar'></ahead>, <time id='dat'>Data</time>, <ul id='rooms'>Rooms</ul>, odpowiednio dla kalendarza, bieżącej daty oraz dla listy pokojów. Dane dla tych elementów pobierane są z serwera AJAX'em.

client/client.js jest skryptem, działającym po stronie klienta(przeglądarki). W szczególności, funkcja setup pobiera z serwera dane, dotyczące dzisiejszego dnia oraz ustawia callbacki na kliknięcie po kalendarzu oraz po liście pokoi.

Callbacki na kliknięcie na kalendarzu oraz na liście pokoi zostało zaimplementowane z użyciem wzorca „delegowanie zdarzeń”. W szczególności po kliknięciu na datę w kalendarzu ładują się dane o rezerwacjach z tej daty.

W pliku lib/reservations.json zapisane są dane o rejestracjach w formacie JSON:


{
   "2014-05-01": {
      "101": true,
      "203": true,
      "304": true
   },
   "2014-05-4": {
      "101": true,
      "102": true
   }
}

Dane są przechowywane po stronie serwera. Na początku pracy serwera dane są wczytywane z pliku i zapisywane w zmiennej reservations:


let reservations;

fs.readFile("lib/reservations.json",'utf-8',
  function(error, data){
    if(error){
      console.log("can't read file");
      process.exit();
    }
    else{
      reservations = JSON.parse(data);
    }
  }
);