Min første Node.js server

Node.js er en cutting edge plattform som skal gjøre det enkelt, eller i alle fall enklere, å lage skalerbare nettverksprogrammer. Den er bygget på toppen av V8, Googles JavaScript-motor som kompilerer JavaScript til maskinkode før den kjøres (i motsetning til å kompilere til bytekode, eller tolke koden).

I motsetning til de fleste, tilsvarende plattformene baserer ikke Node.js sin skalerbarhet på tråding. Node-kode består i å knytte en rekke callbacks opp mot events, og så sover programmet til et av disse eventene inntreffer. Hvert event – f.eks. hver connection i en webserver – bruker veldig lite minne, og blokkerer aldri prosessen. Dessuten er dead-locks helt umulig, for siden det ikke finnes tråder finnes det heller ingen locks.

Node.js integrert med Intouch

Som et første eksepriment med Node.js har jeg laget en mini-website som lister opp mine Intouch-kontakter. PSWinCom Intouch er en webbasert klient for mobil kommunikasjon. Den eksponerer et REST-api som gjør at jeg blant annet kan hente ut informasjon fra kontoen min i XML eller json-format.

Først lager jeg en statisk html-fil som skal vise kontaktene. Den bruker litt jQuery-magi for å hente kontaktene fra Node.js-serveren og viser dem i siden. Jeg kunne selvsagt generert html’en for kontaktene på server-siden, men synes egentlig det er bedre å bruke en Ajax-løsning.

nodejs

UML-diagrammet over viser kommunikasjonsflyten. Jeg har også forsøkt å illustrere forskjellen på en Node.js-basert server og en vanlig webserver som Intouch-serveren representerer; Node.js blokkerer ikke, men er bare aktiv når den har noe å gjøre.

index.html ser ut som dette:

 1 <html>
 2   <head>
 3     <title>My Intouch Contacts</title>
 4     <script type="text/javascript" src="jquery.min.js"></script>
 5     <script type="text/javascript">
 6 
 7     var loadContacts = function() {
 8       var formatContact = function(contact) {
 9         return $("<div>").append(
10           "<b>Name:</b> " + contact.Firstname + 
11           " " + contact.Lastname +
12           " <b>Phone:</b> " +  contact.PhoneNumber);
13       };
14       $.getJSON("/contacts", function(contacts) {
15         $.each(contacts, function() {
16           $("#contacts").append(formatContact(this));
17         });
18       });
19     }
20 
21     $(function() {
22       loadContacts();
23     });
24     </script>
25   </head>
26   <body>
27     <h1>Intouch Contacts</h1>
28     <div id="contacts"></div>
29   </body>
30 </html>

Serveren jeg lager må altså både kunne levere ut index.html og sende kontaktene. Her følger server-koden i sin helhet. Merk at jeg er helt n00b i Node.js, og har klippet og limt litt fra diverse eksempler for å få dette til å virke. Følgende kildekode lagret jeg i en fil jeg kalte server.js.

 1 var sys = require("sys"),
 2     http = require("http"),
 3     url = require("url"),
 4     path = require("path"),
 5     fs = require("fs"),
 6     rest = require("restler");
 7 
 8 function load_static_file(uri, response) {
 9   var filename = path.join(process.cwd(), uri);
10   path.exists(filename, function(exists) {
11     if(!exists) {
12       response.writeHeader(404, {"Content-Type": "text/plain"});
13       response.write("404 Not Found\n");
14       response.close();
15       return;
16     }
17 
18     fs.readFile(filename, "binary", function(err, file) {
19       if(err) {
20         response.writeHead(500, {"Content-Type": "text/plain"});
21         response.end(err + "\n");
22         return;
23       }
24 
25       response.writeHeader(200);
26       response.end(file, "binary");
27     });
28   });
29 }
30 
31 http.createServer(function(request, response) {
32     var uri = url.parse(request.url).pathname;
33     if(uri === "/") {
34       load_static_file("index.html", response);
35       return;
36     }
37     else if(uri === "/contacts") {
38       rest.get("http://intouchapi.pswin.com/1/contacts", {
39           username: 'myuser@mydomain',
40           password: 'mypassword',
41         }).on('complete', function(data) {
42           response.writeHeader(200, { "Content-Type" : "application/json" });
43           response.end(JSON.stringify(data));
44       });
45     }
46     else {
47       console.log("Not supported request " + uri);
48       response.writeHeader(404, {"Content-Type": "text/plain"});
49       response.end("404 Not Found\n");
50     }
51 }).listen(8080);
52 
53 sys.puts("Server running at http://localhost:8080/");

Linje 8 til 29 er kun en funksjon for å serve statiske filer, og det aner meg at det finnes enklere måter å gjøre dette på. Selve serveren registreres på linje 31, hvor jeg legger opp til tre muligheter…

Hvis requesten er “/”, leverer jeg ut index.html-filen. Hvis requesten er “/contacts” gjør jeg et REST-kall til Intouch, og når jeg får svar tilbake derfra sender jeg det bare videre. For alle andre requester svarer jeg tilbake med status 404 Not Found.

Og det var det! Når jeg kjører kommandoen “node server.js” i konsollet, og deretter åpner opp http://localhost:8080/ i en browser, får jeg et resultat som ser ut omtrent som dette:

Intouch Contacts

Name: Ola Nordman Phone: 90807060
Name: Kari Nordman Phone: 90807061
Name: Thor Divel Phone: 90807062
Name: Bob Kåre Phone: 90807063

Mulige utvidelser av denne mini-siten, som vil være ganske enkelt å få til, kan for eksempel være å gi brukeren mulighet til å trykke på en kontakt for å sende ham/henne en SMS-melding. Jeg kunne også ha listet ut kontakt-gruppene mine fra Intouch, og gitt mulighet for å distribuere en SMS til hele gruppen. Mulighetene er mange!

Kategorier: Webutvikling.
RSS feed for kommentarene. Tilbaketråkk.

3 kommentarer til “Min første Node.js server”

  1. Ole-Martin Mørk Says:

    For å serve statiske filer kan du benytte https://github.com/Marak/node-static . Fungerer veldig greit når du skal serve mer enn en fil.

  2. Torbjørn Says:

    Det ante meg at det fantes bibloteker for det ja. Takk for tipset!

  3. JavaScript revolution Says:

    [...] som tar JavaScript server-side, og er basert på Google’s V8-motor som kjører i Chrome. Jeg har lekt meg litt med Node tidligere, og synes det er veldig [...]

Skriv en kommentar

Tillatte tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


Alf Kåre Lefdal: Distributed Podcast er også ganske interessant. De tar opp tema som fx. ...

Stian: +1 for 6er til This Developer's Life! Min definitive favoritt. Jeg trengte også...

Torbjørn: Takk for flere tips, Vegard. Deep Fried Bytes ligger på oversikten min fra 2009...

Vegar: Og glemte helt ios: Nsbrief og ideveloper live. Har du hørt på deep fried byt...

Vegar: Mye kjekt her. TDL, hanselminutes og .net rocks ligger i en klasse for seg. Suv...

Torbjørn: Helt enig, arkivet til Software Engineering Radio er en gullgruve om man vet hva...

Einar W. Høst: Jeg synes at det kuleste med se-radio er backloggen av intervjuer... det er noen...

arnab: fantastisk :)...

Olav: Glimrende blogg ! Modellen av hjernens arbeid passer ikke bare på nyskaping: ...

Torbjørn: Ja, flydesign trekkes ofte frem som et eksempel på dette fenomenet. Design av b...

Mulig relaterte linker

 Hold deg oppdatert

Søk i bloggen

Ferske innlegg

  • NodeJS vs. ASP.NET
  • Pulten min..
  • No ifs and buts
  • Community-fiskebolle på ROOTS 2012
  • Kategorier

  • .net ninja (37)
  • Bøker (18)
  • Diverse prosjekter (37)
  • DSL (10)
  • Erlang (10)
  • F# (5)
  • Hardware (1)
  • Jobb (78)
  • Julekalender (51)
  • kjempekjekt.com (23)
  • LISP/Clojure (34)
  • NDC (4)
  • NNUG / community (63)
  • O/RM & databaser (10)
  • Off topic (118)
  • OO-design/clean code (31)
  • Podcasts (15)
  • Polyglot (82)
  • Ruby (29)
  • Silverlight / RIA (3)
  • Software/verktøy (20)
  • Softwareutvikling (24)
  • Testing / TDD (30)
  • the contiki strip (13)
  • User experience (3)
  • WCF (3)
  • Webutvikling (34)
  • WPF (9)
  • WTF (13)
  • Last ned Wallpaper

    Programmeringsbloggens tøffe skrivebordsbakgrunn med snippets fra ulike språk laster du ned her!

    Abonner via epost

    Om du vil kan du få alle nye blogposter tilsendt til din epost. Abonner nå, det er kjempeenkelt!

    Meta