Kategorien
JavaScript & jQuery Programmierung

Aus der Praxis: Wir bauen eine Chatroom Web-App mit Node.js (Teil 6)

In dieser Node.js Tutorial-Serie zeigen wir, wie man eine Node.js-getriebene Echtzeit-Chatroom Web App erstellt, die vollständig cloud-fähig ist. Es wird darum gehen, Node.js auf einem Windows-Rechner aufzusetzen, ein Web-Frontend mit Express zu entwickeln, eine Node-Express-App auf Azure zu bringen, Socket.IO zu nutzen, um einen Echtzeit-Layer hinzuzufügen und zu zeigen, wie man das Ganze zum Schluss einsetzt.

Aus der Praxis: Wir bauen eine Chatroom Web-App mit Node.js

Schwierigkeitsstufe: Einsteiger bis mittlere Kenntnisse, vorausgesetzt werden HTML5 und JavaScript

Teil 6 – Das Finale: Debugging Remote-Node-Apps

Herzlich willkommen zum sechsten und gleichzeitig letzten Teil unserer Praxis-Serie zu Node.js: Wir programmieren eine Node.js-getriebene Chatroom Web-App.

In dieser letzten Folge geht es um die finale Bereitstellung des Chatrooms. Ich erkläre euch, wie man dabei ein Remote Debugging durchführt.

In Azure bereitstellen!

Unsere Node.js-getriebene anonyme Chatroom-App läuft. Dann wollen wir sie jetzt mit ein paar Klicks auch in der Cloud bereitstellen. Das funktioniert mit jeder Cloud, die Node.js unterstützt. Ich werde hier Microsoft Azure benutzen, weil ich dort auch eine Node.js Website kostenlos laufen lassen kann.

Einen kostenlosen Testzugang für Microsoft Azure gibt es hier. Dieser ermöglicht, Microsoft Azure einen Monat lang im Wert von €170 zu testen. Auf dem Service, den wir hier nutzen, Azure Websites, kann man damit bis zu zehn Webseiten kostenlos laufen lassen.

1. Sobald das Azure-Konto eingerichtet ist, gehen wir zurück zur IDE. Dort führen wir auf unserem Express-Projekt einen Rechtsklick aus und wählen im Menü dann „Publish„.

Wir bauen eine Chatroom Web-App mit Node.js

2. Das Menü „Publish“ öffnet einen Assistenten mit einigen Optionen. Wir wählen als Ziel Microsoft Azure-Websites.

3. An dieser Stelle erfolgt der Login, und zwar mit dem gleichen Microsoft-Konto wie bei der Azure-Anmeldung.

4. Nun wählen wir „New“ aus, um eine neue Azure-Webseite zu erstellen. Existiert schon eine, könnten wir auch einfach diese im Dropdown-Menü auswählen.

clip_image003

5. Nun füllen wir die Felder im Assistenten aus (siehe unten). Darauf achten, einen unverwechselbaren Namen für die Seite zu wählen und dann „Create“ klicken.

BLOG POST - Part 6 - Screenshot 3

6. Als Nächstes erscheint ein vorausgefüllter Assistent mit einem Button „Publish“, den wir klicken.

clip_image007

Geschafft! Das Projekt ist in der Azure-Cloud veröffentlicht! Aber die Arbeit ist damit noch nicht vollständig erledigt.

WebSockets bei Azure-Websites aktivieren

Um sicherzustellen, dass WebSockets auf unserer Website aktiviert ist, müssen wir ein paar weitere Dinge erledigen. Wer sich das Ganze gern etwas detaillierter ansehen oder die FAQ dazu durchstöbern will, sollte sich diese Seite nicht entgehen lassen.

Als erstes aktivieren wir WebSockets von der Azure-Befehlszeile oder dem Konfigurations-Tab aus:

clip_image008

Dann ändern wir unsere web.config Datei und die folgende Zeile zum system.webServer XML-Element.

<webSocket enabled="false" />

Das klingt erstmal unlogisch, ist aber genau richtig so. Denn dieser Schritt deaktiviert das IIS-WebSockets-Modul, das seine eigene WebSockets-Implementierung enthält und mit Node.js-spezifischen WebSockets Modulen wie Socket.IO kollidiert.

Das Debugging von Remote Node Apps

Node Tools für Visual Studio (NTVS) hat etliche fortgeschrittene Debug-Funktionen dabei, wie zum Beispiel bedingte Programmstopps, “Hit Count“- Programmstopps, Tracepoints und Remote Debugging Support für Windows, Linux und OS X. Mehr dazu gibt es hier.

Mit Remote Node-Instanzen verbinden

NTVS unterstützt Remote Debugging Code, der auf Azure-Websites läuft. Im Gegensatz zu gewöhnlichem Remote Debugging ist hier der Zielrechner nicht direkt über TCP zu erreichen. NTVS besitzt dafür einen WebSocket-Proxy für das Debugging-Protokoll, der das Protokoll via HTTP zeigt.

Wenn man ein Windows-Azure-Projekt aufsetzt, ist der Proxy bereits vollständig konfiguriert in Web.Debug.config. Um ihn auf der Azure-Website zu aktivieren, muss man das Projekt in der Debug-Konfiguration veröffentlichen. Das tun wir mit den nun folgenden Schritten.

1. Rechtsklick auf dem Projekt und Publish auswählen.

clip_image001[1]

2. Links den Tab Settings auswählen und im Dropdown-Menü die Konfiguration “Debug” wählen.

clip_image010

3. Auf Publish klicken.

Wenn unser Projekt ordnungsgemäß bereitgestellt und WebSockets aktiviert wurde, können wir die Website vom Server-Explorer aus einfügen. Wer das Server-Explorer-Fenster noch nicht geöffnet hat, kann das über View > Server Explorer tun. Unter Windows Azure > Web Sites können wir dann unsere Website finden. Dort führen wir dann einen Rechtsklick aus. Wenn die Website läuft und das Projekt mithilfe der Debug-Konfiguration bereitgestellt wurde, sollte im Kontextmenü der Attach Debugger (Node.js)-Befehl sichtbar sein.

clip_image011

Protokolle lesen und streamen

Das Streaming der aktuellen Protokolle ist nicht schwierig. Wir müssen einfach im Server-Explorer auf unsere Webseite rechtsklicken und View Streaming Logs auswählen.

clip_image012

Fazit

Glückwunsch! Wir haben es vollbracht! Der anonyme Echtzeit-Chatroom läuft in der Cloud. In dieser Tutorial-Serie haben wir nicht nur gelernt, wie man Node aufsetzt, ein Web-Frontend mit Express entwickelt und die App in die Cloud bringt, sondern auch wie man socket.io nutzt, um einen Echtzeit-Layer einzufügen. Zu guter Letzt wissen wir nun auch, wie man das Ganze am Ende bereitstellt.

clip_image013

Wer will, kann die einzelnen Teile noch mal auf meinem Blog nachlesen (in englischer Sprache). Hin und wieder stelle ich dort auch Updates zu diesem Tutorial bereit. Wer mehr Neuigkeiten dazu erfahren will, kann mir einfach auf Twitter folgen @ramisayar.

P.S. Ja, auch für noch mehr „Hurra-GIFs“ habe ich einen Link-Tipp.

Alle Teile der Node.js-Serie hier bei Dr. Web

#1: Einführung in Node.js

#2: Express mit Node.js und Azure

#3: Ein Chatroom-Backend mit Node.js, Socket.IO und Mongo aufsetzen

#4: Eine Chatroom-UI mit Bootstrap erstellen

#5: Den Chatroom mit WebSockets verbinden

#6: Das Finale: Debugging Remote-Node-Apps (dieser Beitrag)

Noch mehr Lernmaterial zu Node.js auf Azure

Ausführlichere Lehrinhalte zu Node gibt es in meinem Kurs an der Microsoft Virtual Academy.

Sehr hilfreich sind auch diese Kurzvideos zu ähnlichen Node-Themen:

Dieser Artikel ist Teil der Web-Dev Tech-Series von Microsoft. Wir freuen uns Microsoft Edge (früher Project Spartan genannt) und seine neue Rendering Engine mit euch zu teilen. Kostenlose Virtual Machines oder Remote Testings für Mac, iOS, Android oder Windows gibt es hier: @ dev.modern.IE.

(dpe)

Kategorien
JavaScript & jQuery Programmierung

Aus der Praxis: Wir bauen eine Chatroom Web-App mit Node.js (Teil 5)

In dieser Node.js Tutorial-Serie zeigen wir, wie man eine Node.js-getriebene Echtzeit-Chatroom Web App erstellt, die vollständig cloud-fähig ist. Es wird darum gehen, Node.js auf einem Windows-Rechner aufzusetzen, ein Web-Frontend mit Express zu entwickeln, eine Node-Express-App auf Azure zu bringen, Socket.IO zu nutzen, um einen Echtzeit-Layer hinzuzufügen und zu zeigen, wie man das Ganze zum Schluss einsetzt.

Wir bauen eine Chatroom Web-App mit Node.js (Teil 5)

Schwierigkeitsstufe: Einsteiger bis mittlere Kenntnisse, vorausgesetzt werden HTML5 und JavaScript

Teil 5 – Den Chatroom mit WebSockets verbinden

Willkommen zurück zu Teil 5 unserer Praxis-Serie zu Node.js: Wir programmieren eine Node.js-getriebene Chatroom Web-App.

In diesem Teil erkläre ich, wie man den Frontend-Chatroom mit dem Node-Chatroom-Backend verbindet, das wir in Teil 2, Teil 3 und Teil 4 erstellt haben.

Hinzufügen von jQuery, SocketIO und index.js

Bevor wir beginnen, unseren Frontend-JavaScript-Code zu schreiben, sollten wir sicherstellen, dass alle benötigten Dateien und Abhängigkeiten vom Node-Server ausgeliefert werden. Zu Beginn fügen wir jQuery und Socket.IO der Datei layout.jade hinzu, die durch alle anderen jade Dateien unseres Projekts erweitert wird.

WIr ersetzen den Link zu bootstrap.min.js mit einem Link zu allen Dateien, die wir benötigen.

script(type='text/javascript' src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js')
script(type='text/javascript' src='/js/bootstrap.min.js')
script(type='text/javascript' src='/socket.io/socket.io.js')

Beachte: die erste Zeile verweist auf jQuery, das im Microsoft Ajax Content Delivery Network gehostet wird. Dieses CDN beinhaltet beliebte JavaScript-Bibliotheken von Drittanbietern, wie jQuery. Dadurch kann man diese sehr einfach den eigenen Webanwendungen hinzufügen. Die Performance von Ajax-Anwendungen wird durch die Nutzung eines CDN deutlich verbessert. Die Inhalte eines CDN werden auf weltweit verteilten Servern zwischengespeichert. Das CDN unterstützt SSL (HTTPS) für den Fall, dass man eine Webseite mit der Hilfe von Secure Sockets Layer ausliefern will.

Nun füge ich am Ende eine weitere Zeile hinzu, um einen neuen Block zu erstellen.

block body_end

Dadurch kann jede Jade-Datei, die eine layout.jade Erweiterung hat, auch Script-Tags unmittelbar vor dem Ende des Body-Tags einfügen.

Jetzt nutzen wir unseren neuen Block, um dort einen Link zu unserer index.js-Datei einzufügen, die wir im Ordner public/js erstellen werden (bitte nicht vergessen).

block body_end
  script(type='text/javascript' src='/js/index.js')

Wichtig: Der Block beginnt ohne Einzug, um den Code-Konventionen von Jade zu genügen. Wer jetzt den Node-Server ausführt und zur Hauptseite seines Browsers geht, wird in den F12-Tools entdecken, dass die Dateien korrekt ausgeliefert werden.

Schnelle Anpassungen in app.js

Jetzt würde ich gern paar Dinge in app.js ändern. Als erstes will ich die Reihenfolge der Sortierung umkehren – damit die ältesten Mitteilungen zuerst gesendet werden. Außerdem sollen die neuesten Chat-Nachrichten auf dem gleichen Kanal gesendet werden, auf dem die neuen Nachrichten empfangen werden. Diese Änderungen vollziehe ich in den Zeilen 49 und 50 von app.js. Und so sieht es dann aus:

var stream = collection.find().sort().limit(10).stream();
stream.on('data', function (chat) { socket.emit('chat', chat.content); });

Nicht vergessen: Die Umgebungsvariable CUSTOMCONNSTR_MONGOLAB_URI muss festgelegt werden, bevor die app.js-Datei erneut aufgerufen wird, da ansonsten das Node-Backend abstürzt, weil es keine Verbindung zur MongoDB herstellen kann.

Den Send-Button aktivieren

Nun ist es an der Zeit, den Send-Button zu aktivieren, um mithilfe von WebSockets Nachrichten im Mitteilungsfeld an den Backend-Server des Chat-Channels zu senden.

var socket = io();
$('#send-message-btn').click(function () {
    var msg = $('#message-box').val();
    socket.emit('chat', msg);
    $('#messages').append($('
').text(msg)); $('#message-box').val(''); return false; }); socket.on('chat', function (msg) { $('#messages').append($('

').text(msg)); });

Zeile 1

Wir erstellen ein Socket, indem wir die Funktion io() aufrufen, die sich in der Datei socket.io-client.js befindet.

Zeile 2

Danach sorgen wir dafür, dass durch einen Klick auf den Send-Message-Button eine Funktion ausgeführt wird. Dafür nutzen wir die Funktion $ von jQuery und den Click-Event-Handler.

Zeile 3

Wir erhalten den String-Value des Mitteilungsfensters mithilfe der Funktion $ von jQuery.

Zeile 4

Wir nutzen die emit-Funktion auf der Socket-Variable, die wir in Zeile 1 erstellt haben, um eine Mitteilung an den ‘chat’-Channel zu senden, die den Wert des Mitteilungsfensters enthält.

Zeilen 5-7

Hier fügen wir die Nachricht im Mitteilungsfenster der Div #messages hinzu, damit der User erkennt, dass die Nachricht gesendet wurde. Wir weisen den Wert des Mitteilungsfensters einem leeren String zu, um es wieder frei zu machen.

Zeilen 9-10

Wir wollen die im Chat-Channel erhaltenen Nachrichten anderer User der Div #messages hinzufügen. Das Node-Backend wird die vom Client geschriebene Mitteilung nicht an sich selbst zurücksenden. Aber das geht in Ordnung, weil wir diese schon im Click-Handler eingefügt haben.

Wir bauen eine Chatroom Web-App mit Node.js (Teil 5)

Fazit

Geschafft! Wir haben Backend und Frontend mithilfe von WebSockets verbunden. Wer jetzt noch eine Identifikation oder Avatare für alle User hinzufügen will – kein Problem. Aber auch ohne das ist der Chatroom jetzt einsatzbereit. In der nächsten Folge erkläre ich wie der Chatroom auf Azure angewendet und von Fehlern befreit wird.

Dranbleiben für Teil 6!

Teil 6 — das Finale mit dem Debugging von Remote Node Apps — wird schon bald hier bei Dr. Web veröffentlicht. In englischer Sprache gibt es ihn schon auf meinem Blog.

Wer mehr Neuigkeiten dazu und zu anderen Artikeln erfahren will, kann mir einfach auf Twitter folgen: @ramisayar.

Weitere Teile der Serie bei MSDN (in englischer Sprache)

Part 1 – Introduction to Node.js
Part 2 – Welcome to Express with Node.js and Azure
Part 3 – Building a Backend with Node, Mongo and Socket.IO
Part 4 – Building a Chatroom UI with Bootstrap
Part 5 – Connecting the Chatroom with WebSockets
Part 6 – The Finale and Debugging Remote Node Apps

Noch mehr Lernen über Node auf Azure

Ausführlichere Lehrinhalte zu Node gibt es in meinem Kurs an der Microsoft Virtual Academy.

Sehr hilfreich sind auch diese Kurzvideos zu ähnlichen Node-Themen:

Dieser Artikel ist Teil der Web-Dev Tech-Series von Microsoft. Wir freuen uns Microsoft Edge (früher Project Spartan genannt) und seine neue Rendering Engine mit euch zu teilen. Kostenlose Virtual Machines oder Remote Testings für Mac, iOS, Android oder Windows gibt es hier: @ dev.modern.IE.

(dpe)

Kategorien
JavaScript & jQuery Programmierung

Aus der Praxis: Wir bauen eine Chatroom Web-App mit Node.js (Teil 4)

In dieser Node.js Tutorial-Serie zeigen wir, wie man eine Node.js-getriebene Echtzeit-Chatroom Web App erstellt, die vollständig cloud-fähig ist. Es wird darum gehen, Node.js auf einem Windows-Rechner aufzusetzen, ein Web-Frontend mit Express zu entwickeln, eine Node-Express-App auf Azure zu bringen, Socket.IO zu nutzen, um einen Echtzeit-Layer hinzuzufügen und zu zeigen, wie man das Ganze zum Schluss einsetzt.

Aus der Praxis: Wir bauen eine Chatroom Web App mit Node.js (Teil 4)

Schwierigkeitsstufe: Einsteiger bis mittlere Kenntnisse, vorausgesetzt werden HTML5 und JavaScript

Teil 4 – Eine Chatroom-UI mit Bootstrap erstellen

Willkommen zurück zu Teil 4 unserer Praxis-Serie zu Node.js: Wir programmieren eine Node.js-getriebene Chatroom Web-App. In diesem Teil erkläre ich, wie man ein mit Bootstrap entworfenes Frontend dem Chatroom-Backend hinzufügt, welches wir in Teil 2 und Teil 3 gebaut haben.

Was ist Bootstrap?

Bootstrap ist ein sehr weit verbreitetes und beliebtes HTML- und CSS-Framework, um Websites und Web-Anwendungen zu erstellen. Es ist mit Abstand das Top-Projekt bei GitHub. Bootstrap unterstützt responsives Webdesign, wodurch eine Webseite unabhängig vom Gerät korrekt dargestellt wird, egal ob auf dem Desktop-Computer, einem Tablet oder anderen Mobilgeräten, wie Smartphones etc.

Bootstrap dem Projekt hinzufügen

Um Bootstrap unserem Projekt hinzuzufügen, müssen wir die verkleinerten CSS- und JS-Dateien für Bootstrap herunterladen. Das ist hier möglich. Nach dem Download von Bootstrap gilt es, die Datei zu entpacken und die Ordner “css”, “js” und “fonts” in den “public”-Ordner unseres Projekts zu kopieren.

In unserer bestehenden Ordnerstruktur fallen jetzt ein paar Unstimmigkeiten ins Auge. Wir werden daher die Stylesheets- und JavaScript-Ordner vereinheitlichen. Ich persönlich bevorzuge die Bootstrap-Benennungen, das heißt “css” statt “stylesheets” und “js” statt “javascripts”, da diese mit den Libraries von Drittanbietern geteilt werden. Nun kopieren wir die Dateien von “stylesheets” in “css” und löschen den “javascripts” Ordner, der jetzt leer sein sollte. In layout.jade ändern wir dann die folgende Zeile:

link(rel='stylesheet' href='/stylesheets/style.css')

zu:

link(rel='stylesheet' href='/css/style.css')

Als nächstes fügen wir die Bootstrap-CSS-Links im Header und die entsprechenden Meta-Tags für HTML5-Apps in der layout.jade-Datei hinzu. Die folgenden Zeilen müssen vor der Zeile mit dem style.css-Link eingefügt werden.

meta(charset="utf-8")
meta(http-equiv="X-UA-Compatible" content="IE=edge")
link(rel='stylesheet' href='/css/bootstrap.min.css')
link(rel='stylesheet' href='/css/bootstrap-theme.min.css')

Nun fügen wir die JavaScript-Datei hinzu, die Bootstrap für seine Komponenten und Plugins benötigt. Dazu fügen wir die folgende Zeile am Ende von layout.jade ein:

script(type='text/javascript' src='/js/bootstrap.min.js')

Vollständiges layout.jade

doctype html
html
  head
    title= title
    meta(charset="utf-8")
    meta(http-equiv="X-UA-Compatible" content="IE=edge")
    link(rel='stylesheet' href='/css/bootstrap.min.css')
    link(rel='stylesheet' href='/css/bootstrap-theme.min.css')
    link(rel='stylesheet' href='/css/style.css')

  body
    block content

    script(type='text/javascript' src='/js/bootstrap.min.js')

Erstellen des Chat-UI-Layouts

Jetzt ist das Chat-Userinterface-Layout an der Reihe. Hier ist es sicher hilfreich, sich tiefer in Bootstrap einzulesen und dieses etwas längere Tutorial anzuschauen. Alle Chat-Engines haben einen Bereich für die aktuellen Mitteilungen und einen Bereich, in dem die Nutzer Mitteilungen schreiben und senden können. Traditionell war das Layout so gestaltet, dass die Mitteilungen oben erschienen und das Schreibfeld unten positioniert war.

Es erfordert einen gewissen Aufwand, um in HTML ein Element am unteren Rand des Viewports zu fixieren. Ich werde mich dafür an diesem Beispiel orientieren, um unten eine Fußzeile zu fixieren. Dazu modifizieren wir die index.jade-Datei und entfernen alle Code-Zeilen unterhalb des Content-Blocks.
Zunächst fügen wir den Seitenbereich ein, der die ankommenden Mitteilungen enthalten soll.

Dazu fügen wir erstmal eine div mit der Klasse wrap hinzu. In Jade müssen wir einfach nur wrap schreiben, um eine <div class=”wrap”></div> zu erstellen. Indem wir den Einzug nutzen, teilen wir der Jade-Templating-Engine mit, dass mehr eingerückte Elemente innerhalb der weniger eingerückten Elemente stehen.

Wer es in den anderen Teilen des Tutorials verpasst hat: Dieses Jade-Tutorial lohnt sich wirklich.

Als nächstes fügen wir eine weitere div mit der Klasse container-fluid hinzu, um der Seite eine flexible Breite zu geben. Dazu kommt ein H1-Element: “Welcome to the Node Chatroom” sowie eine div mit einer ID messages und schließlich eine div mit der Klasse push, mit dem wir das Bearbeitungsfeld für Mitteilungen im Chatroom an das untere Ende des Viewports schieben.

  .wrap
    .container-fluid
        h1 Welcome to the Node Chatroom
        #messages

        .push

Nun gehen wir daran, das Schreibfeld zu programmieren. Dabei wollen wir das Textfeld und den Sende-Button in einer div namens Footer und einer div namens „container-fluid“ erfassen. Das Footer div hat den gleichen Einzug wie das wrap div.

Jetzt nutzen wir das Bootstrap-Grid-System (mehr dazu hier) um das Textfeld in zwei Teile zu trennen. In der größeren Spalte wird man die Mitteilungen schreiben können, die andere enthält den Block-Level-Button, mit dem man die Nachricht absenden kann.

Deutlich wird, dass Jade uns ermöglicht, die Attribute eines Elements mit Hilfe der Absatzvermerke genau festzulegen. Der Code sieht dann wie folgt aus:

  .footer
    .container-fluid
      .row
        .col-xs-8.col-sm-9
          input(type="text" id="message-box" class="form-control input-lg" placeholder="Write a message here..." rows="3")
        .col-xs-4.col-sm-3
          button#send-message-btn.btn.btn-primary.btn-lg.btn-block Send Message

Vollständiges index.jade

extends layout

block content
  .wrap
    .container-fluid
        h1 Welcome to the Node Chatroom
        #messages

        .push
  .footer
    .container-fluid
      .row
        .col-xs-8.col-sm-9
          input(type="text" id="message-box" class="form-control input-lg" placeholder="Write a message here..." rows="3")
        .col-xs-4.col-sm-3
          button#send-message-btn.btn.btn-primary.btn-lg.btn-block Send Message

Mit CSS das Textfeld unten fixieren

Um das Textfeld unten in der Ansicht zu fixieren, werden wir einige benutzerdefinierte CSS zur Seite public/css/style.styl hinzufügen. Diese Datei nutzt den Stylus CSS-Präprozessor, aber man kann auch textbasiertes CSS kopieren, welches erneut in die erstellte CSS-Datei kopiert wird.

Zunächst stellen wir sicher, dass die ganze Seite wirklich 100% der Höhe einnimmt.

html, body
  height: 100%

Dann achten wir darauf, dass der Wrap-Bereich die maximal mögliche Höhe einnimmt, aber unten einen Rand von 60px für unsere Fußzeile und das Textfeld lässt.

.wrap 
  min-height: 100%
  height: auto !important
  height: 100%
  margin: 0 auto -60px

Nun stellen wir sicher, dass die Fläche für den Textbereich berücksichtigt wird und ordnen diese der Fußzeile zu.

.push, .footer 
  height: 60px

Um zum Schluss noch etwas stylisch zu werden, geben wir der Fußzeile eine dezente Hintergrundfarbe.

.footer
  background-color: #f5f5f5

Vollständige Style.styl

html, body
  height: 100%
 
.wrap 
  min-height: 100%
  height: auto !important
  height: 100%
  margin: 0 auto -60px
 
.push, .footer 
  height: 60px
 
.footer
  background-color: #f5f5f5

Screenshot

Fazit

Perfekt! Wir haben Bootstrap und die Jade/Stylus-Präprozessoren genutzt, um unseren Node-basierten Chatroom mit einem netten UI-Layout auszustatten. Im nächsten Teil werde ich erklären, wie man die UI und das Node-Backend via WebSockets verbindet.

Dranbleiben für Teil 5!

Teil 5 — Den Chatroom mit WebSockets verbinden — wird schon bald hier bei Dr. Web veröffentlicht. Wer mehr Neuigkeiten dazu und zu anderen Artikeln erfahren will, kann mir einfach auf Twitter folgen: @ramisayar.

Weitere Teile der Serie bei MSDN (in Englisch)

Part 1 – Introduction to Node.js
Part 2 – Welcome to Express with Node.js and Azure
Part 3 – Building a Backend with Node, Mongo and Socket.IO
Part 4 – Building a Chatroom UI with Bootstrap
Part 5 – Connecting the Chatroom with WebSockets
Part 6 – The Finale and Debugging Remote Node Apps

Noch mehr Lernen über Node auf Azure

Ausführlichere Lehrinhalte zu Node gibt es in meinem Kurs an der Microsoft Virtual Academy.

Sehr hilfreich sind auch diese Kurzvideos zu ähnlichen Node-Themen:

Dieser Artikel ist Teil der Web-Dev Tech-Series von Microsoft. Wir freuen uns Microsoft Edge (früher Project Spartan genannt) und seine neue Rendering Engine mit euch zu teilen. Kostenlose Virtual Machines oder Remote Testings für Mac, iOS, Android oder Windows gibt es hier: @ dev.modern.IE.

(dpe)

Kategorien
JavaScript & jQuery Programmierung

Aus der Praxis: Wir bauen eine Chatroom Web-App mit Node.js (Teil 3)

In dieser Node.js Tutorial-Serie zeigen wir, wie man eine Node.js-getriebene Echtzeit-Chatroom Web App erstellt, die vollständig cloud-fähig ist. Es wird darum gehen, Node.js auf einem Windows-Rechner aufzusetzen, ein Web-Frontend mit Express zu entwickeln, eine Node-Express-App auf Azure zu bringen, Socket.IO zu nutzen, um einen Echtzeit-Layer hinzuzufügen und zu zeigen, wie man das Ganze zum Schluss einsetzt.

Aus der Praxis: Wir bauen eine Chatroom Web-App mit Node.js (Teil 3)

Schwierigkeitsstufe: Einsteiger bis mittlere Kenntnisse, vorausgesetzt werden HTML5 und JavaScript.

Teil 3 – Ein Chatroom Backend mit Node.js, Socket.IO und Mongo aufsetzen

Willkommen zurück zu Teil 3 der Praxis-Tutorialserie zu Node.js: Wir programmieren eine Node.js-getriebene Chatroom-Web-App. In diesem Teil erkläre ich, wie man die bestehende Express-basierte Node.js-App nutzt, um ein Chatroom-Backend mit WebSocket-Unterstützung zu erstellen.

Was sind WebSockets? Was ist Socket.IO?

WebSocket ist ein Netzwerkprotokoll, mit dem Web-Anwendungen eine bidirektionale Verbindung zwischen Webbrowser und Webserver über TCP aufbauen können. Es ist vollständig kompatibel mit HTTP und nutzt den TCP-Port 80. WebSocket ermöglicht Web-Anwendungen in Echtzeit und fortgeschrittene Interaktionen zwischen Client und Server. Das Protokoll wird von zahlreichen Servern unterstützt, darunter Edge und Internet Explorer, Google Chrome, Firefox, Safari und Opera.

Socket.IO ist eine JavaScript-Library und ein Node.js-Modul. Damit gelingt es sehr einfach und schnell, bidirektionale, event-basierte Kommunikations-Apps zu erstellen. Die Nutzung von WebSockets wird dadurch stark vereinfacht. Wir werden für unsere Chatroom-App Socket.IO v1.0 benutzen.

Socket.IO zu package.json hinzufügen

Package.json ist eine Datei, die verschiedene Metadaten enthält, die für das Projekt relevant sind, einschließlich ihrer Abhängigkeiten. NPM nutzt diese Datei, um Module zu laden, die für das Projekt benötigt werden. Hier lohnt es sich, einen Blick auf diese interaktive Erklärung von package.json und was alles drin steckt, zu werfen.
Nun fügen wir Socket.IO dem Projekt als Abhängigkeit hinzu. Das kann man auf zweierlei Weise tun.

1. Wer schon die anderen Teile der Tutorial-Serie verfolgt und bereits ein Projekt im Visual Studio Setup erstellt hat, braucht nur einen Rechtsklick auf den NPM-Teil des Projekts auszuführen, um dann “Install New npm Packages…” auszuwählen.

clip_image002

Nachdem sich das Fenster geöffnet hat, suchen wir nach “socket.io”, wählen das oberste Ergebnis aus und machen ein Häkchen bei “Add to package.json”. Dann klicken wir den Button “Install Package”. Nun wird Socket.IO in unserem Projekt installiert und zur package.json-Datei hinzugefügt.

clip_image004

package.json

{
  "name": "NodeChatroom",
  "version": "0.0.0",
  "description": "NodeChatroom",
  "main": "app.js",
  "author": {
    "name": "Rami Sayar",
    "email": ""
  },
  "dependencies": {
    "express": "3.4.4",
    "jade": "*",
    "socket.io": "^1.0.6",
    "stylus": "*"
  }
}

2. Wer mit OS X oder Linux arbeitet, muss den folgenden Befehl im Root-Verzeichnis des Projektordners ausführen, um das gleiche Ergebnis zu erhalten.

npm install --save socket.io

Socket.IO der app.js hinzufügen

Im nächsten Schritt fügen wir Socket.IO der app.js hinzu. Dazu suchen wir den folgenden Code:

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

Und ersetzen ihn durch:

var serve = http.createServer(app);
var io = require('socket.io')(serve);

serve.listen(app.get('port'), function () {
    console.log('Express server listening on port ' + app.get('port'));
});

Auf diese Weise wird der HTTP-Server in einer Variable namens serve erfasst und übermittelt, so dass das Socket.IO Modul sich diesem zuordnet. Der letzte Block des Codes nimmt die Variable serve und führt die Funktion listen aus, welche den HTTP-Server startet.

Protokollieren, wenn User kommen und gehen

Gut wäre es natürlich, protokollieren zu können, wenn ein User den Chatroom betritt. Das gelingt mit dem folgenden Code. Er löst bei jedem connection Event eine Callback-Funktion via WebSocket an unseren HTTP-Server aus. In der Callback-Funktion rufen wir console.log auf, um zu protokollieren, dass ein User anwesend ist. Wir können diesen Code hinzufügen, nachdem wir serve.listen aufgerufen haben.

io.on('connection', function (socket) {
    console.log('a user connected');
});

Um auch festzuhalten, wann ein User den Chatroom verlässt, müssen wir das disconnect Event für jedes Socket verbinden. Wir fügen dazu den folgenden Code nach dem console.log des vorhergehenden Code-Blocks hinzu.

    socket.on('disconnect', function () {
        console.log('user disconnected');
    });

Und so sieht der Code dann aus:

io.on('connection', function (socket) {
    console.log('a user connected');
    socket.on('disconnect', function () {
        console.log('user disconnected');
    });
});

Senden einer Mitteilung aus dem Chat-Channel

Socket.IO besitzt eine Funktion namens emit, um Events zu übertragen.
Nach dem Empfang einer Mitteilung im Chat-Channel, wird sie durch den Aufruf von emit mit dem Sende-Marker in der Callback-Funktion an alle anderen Verbindungen auf diesem Socket gesendet.

socket.on('chat', function (msg) {
    socket.broadcast.emit('chat', msg);
});

So sieht der Code dann aus:

io.on('connection', function (socket) {
    console.log('a user connected');
    socket.on('disconnect', function () {
        console.log('user disconnected');
    });
 
    socket.on('chat', function (msg) {
        socket.broadcast.emit('chat', msg);
    });
});

Mitteilungen in einer NoSQL-Datenbank sichern

Der Chatroom sollte Chat-Mitteilungen in einem einfachen Datenspeicher sichern. Für gewöhnlich gibt es zwei Wege, um Datenbestände in Node zu speichern. Entweder man nutzt einen Datenbank-spezifischen Driver oder eine ORM. In diesem Tutorial werde ich MongoDB nutzen, um die Mitteilungen zu sichern. Natürlich gibt es viele weitere Möglichkeiten, einschließlich SQL-Datenbanken wie PostgreSQL oder MySQL.

Als erstes stellen wir sicher, dass wir eine MongoDB haben, mit der wir uns verbinden können. Diese kann man auch von Drittanbietern, wie MongoHQ oder MongoLab, hosten lassen. In diesem Tutorial wird sehr gut gezeigt, wie man eine MongoDB mit Hilfe des MongoLab-Add-On in Azure erstellt. Für unsere Zwecke reicht es hier, bis zu “Create the App” zu lesen. Hauptsache, wir haben die MONGOLAB_URI irgendwo gespeichert und können auf diese später leicht zugreifen.

Nachdem wir die MongoDB erstellt haben und MONGOLAB_URI für die Datenbank haben (zu finden unter Connection-Information in der Zwischenablage), werden wir dafür sorgen, dass der URI für die Anwendung verfügbar ist. Es ist nicht zu empfehlen, vertrauliche Informationen wie diesen URI in den Code oder in eine Konfigurationsdatei unseres Quellcode-Management-Tools einzubauen.

Wir können den Wert der Connection-Strings-Liste im Konfigurationsmenü unserer Azure-Web-Anwendung hinzufügen (wie im vorhergehenden Tutorial beschrieben) oder wir fügen ihn der App-Setting-Liste hinzu (mit dem Namen CUSTOMCONNSTR_MONGOLAB_URI). Auf unserem lokalen Rechner können wir den Wert den Umgebungsvariablen hinzufügen; mit dem Namen CUSTOMCONNSTR_MONGOLAB_URI und dem Wert des URI.

Im nächsten Schritt sorgen wir dafür, dass unser Projekt MongoDB unterstützt. Das gelingt, indem wir die folgende Zeile dem Abhängigkeiten-Objekt in package.json hinzufügen. Vergesst dabei nicht das Sichern der Änderungen in der Datei.

"mongodb": "^1.4.10",

Es folgt ein Rechtsklick im NPM-Teil der Projekts im Solution-Explorer, um das Kontextmenü anzeigen zu lassen. Jetzt “Install missing npm packages” klicken, um das MongoDB Paket zu installieren und es damit als Modul nutzbar zu machen.

clip_image005

Nun importieren wir dieses Modul, um das MongoDB-Client-Object in app.js nutzen zu können. Dafür fügen wir die folgenden Code-Zeilen nach den ersten require(‘’) Funktionsaufrufen ein, wie in Zeile 11.

var mongo = require('mongodb').MongoClient;

Nun wollen wir uns mit der Datenbank mit Hilfe des URI verbinden, das uns in der CUSTOMCONNSTR_MONGOLAB_URI-Umgebungsvariable vorliegt. Nachdem wir verbunden sind, fügen wir die Chat-Mitteilung ein, die über die Socket-Verbindungen empfangen wurde.

mongo.connect(process.env.CUSTOMCONNSTR_MONGOLAB_URI, function (err, db) {
    var collection = db.collection('chat messages');
    collection.insert({ content: msg }, function (err, o) {
        if (err) { console.warn(err.message); }
        else { console.log("chat message inserted into db: " + msg); }
    });
});

Deutlich im obigen Code zu sehen: Wir nutzen das process.env-Objekt, um den Wert der Umgebungsvariable zu erhalten. Nun begeben wir uns in eine Collection in der Datenbank und rufen die Insert-Funktion mit dem Inhalt in einem Objekt auf.

Nun wird jede Mitteilung in der MongoDB-Datenbank gespeichert.

Aussenden der zehn aktuellsten Mitteilungen

Natürlich sollen sich die User nicht total verloren fühlen, nachdem sie den Chatroom betreten haben. Daher ist es sicher sinnvoll, die letzten zehn erhaltenen Mitteilungen vom Server zu senden, um den Usern etwas Kontext zu geben. Dafür müssen wir Mongo verbinden. In diesem Fall nehme ich davon Abstand, den gesamten Socket-Code mit nur einer Verbindung in die Datenbank zu schicken. So ist sicher gestellt, dass der Server weiter arbeiten kann, auch wenn die Verbindung zur Datenbank mal verloren geht.

Um die Liste zu sortieren, und die Anfrage tatsächlich auf die zehn aktuellsten Mitteilungen zu beschränken, nutzen wir die von MongoDB generierte _id, da sie einen Zeitmarker enthält (in komplexeren Anwendungen ist es stets angebracht, einen Zeitmarker für jede Mitteilung zu haben). Jetzt rufen wir die limit-Funktion auf, um unsere Liste auf zehn Mitteilungen zu beschränken.

Wir streamen die Ergebnisse von MongoDB, damit sie an den Chatroom ausgesendet werden können, sobald sie eingetroffen sind.

mongo.connect(process.env.CUSTOMCONNSTR_MONGOLAB_URI, function (err, db) {
    var collection = db.collection('chat messages')
    var stream = collection.find().sort({ _id : -1 }).limit(10).stream();
    stream.on('data', function (chat) { socket.emit('chat', chat.content); });
});

Der obige Code erledigt den Job genau so, wie in den vorhergehenden Absätzen beschrieben.

Auf Azure anwenden

Um das Ganze wieder auf Azure laufen zu lassen, kann man einfach den Schritten folgen, die in den vergangenen Teilen des Tutorials beschrieben wurden (zum Beispiel in Teil 2).

Fazit

Nun haben wir ein Chat-System erstellt, das über WebSockets empfangene Mitteilungen an alle verbundenen Clients aussendet. Außerdem sichert es die Nachrichten in einer Datenbank und stellt die zehn aktuellsten Mitteilungen bereit, um allen Usern, die den Chatroom betreten, ausreichend Kontext zu geben.

Und jetzt heißt es: dran bleiben. Denn Teil 4 — Eine Chatroom-UI mit Bootstrap erstellen — wird schon bald hier bei Dr. Web veröffentlicht. Wer mehr Neuigkeiten dazu und zu anderen Artikeln erfahren will, kann mir einfach auf Twitter folgen @ramisayar.

Weitere Teile der Serie bei MSDN (in englischer Sprache)

Part 1 –  Introduction to Node.js
Part 2  – Welcome to Express with Node.js and Azure
Part 3 – Building a Backend with Node, Mongo and Socket.IO
Part 4 – Building a Chatroom UI with Bootstrap
Part 5 – Connecting the Chatroom with WebSockets
Part 6 – The Finale and Debugging Remote Node Apps

Noch mehr Lernen über Node auf Azure

Ausführlichere Lehrinhalte zu Node gibt es in meinem Kurs an der Microsoft Virtual Academy.

Sehr hilfreich sind auch diese Kurzvideos zu ähnlichen Node-Themen:

Dieser Artikel ist Teil der Web-Dev Tech-Series von Microsoft. Wir freuen uns Microsoft Edge (früher Project Spartan genannt) und seine neue Rendering Engine mit euch zu teilen. Kostenlose Virtual Machines oder Remote Testings für Mac, iOS, Android oder Windows gibt es hier: @ dev.modern.IE.

Zur besseren Übersicht und als Extra-Service folgt hier der gesamte Quellcode der app.js

//
/**
 * Module dependencies.
 */

var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');

var mongo = require('mongodb').MongoClient;

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.index);
app.get('/users', user.list);

var serve = http.createServer(app);
var io = require('socket.io')(serve);

serve.listen(app.get('port'), function () {
    console.log('Express server listening on port ' + app.get('port'));
});

io.on('connection', function (socket) {
    console.log('a user connected');

    mongo.connect(process.env.CUSTOMCONNSTR_MONGOLAB_URI, function (err, db) {
        var collection = db.collection('chat messages')
        var stream = collection.find().sort({ _id : -1 }).limit(10).stream();
        stream.on('data', function (chat) { socket.emit('chat', chat); });
    });

    socket.on('disconnect', function () {
        console.log('user disconnected');
    });

    socket.on('chat', function (msg) {
        mongo.connect(process.env.CUSTOMCONNSTR_MONGOLAB_URI, function (err, db) {
            var collection = db.collection('chat messages');
            collection.insert({ content: msg }, function (err, o) {
                if (err) { console.warn(err.message); }
                else { console.log("chat message inserted into db: " + msg); }
            });
        });

        socket.broadcast.emit('chat', msg);
    });
});

(dpe)

Kategorien
JavaScript & jQuery Programmierung

Aus der Praxis: wir bauen eine Chatroom Web-App mit Node.js (Teil 2)

In dieser Node.js Tutorial-Serie zeigen wir, wie man eine Node.js-getriebene Echtzeit-Chatroom Web App erstellt, die vollständig cloud-fähig ist. Es wird darum gehen, Node.js auf einem Windows-Rechner aufzusetzen, ein Web Frontend mit Express zu entwickeln, eine Node Express App auf Azure zu bringen, wie man Socket.IO nutzt um einen Echtzeit-Layer hinzuzufügen und wie man das Ganze zum Schluss einsetzt.

nodejs-parttwo-teaser_DE
Schwierigkeitsstufe: Einsteiger bis mittlere Kenntnisse, vorausgesetzt werden HTML5 und JavaScript.

Teil 2: Express mit Node.js und Azure

Hier nun also Teil 2 der Praxis-Tutorialserie über Node.js: Wir programmieren eine Node.js-getriebene Chatroom Web App. In diesem Teil erkläre ich wie man ein neues Express-basiertes Node-Projekt aufsetzt und es auf Azure laufen lässt.

Was ist Express?

Express ist ein minimalistisches, flexibles Open Source Web-Framework, welches die Entwicklung von Webseiten, Web Apps und APIs erheblich vereinfacht.

Wofür ist Express gut?

Express erleichtert es dank Route Support HTTP Requests zu beantworten, Responses können dadurch an bestimmte URLs geschrieben werden. Express unterstützt zudem mehrere Template Engines, um die Erstellung von HTTP Responses zu vereinfachen.

Alles bereit und Node.js installiert? Wer Hilfe braucht, schaut einfach noch mal in Teil 1: Einführung in Node.js.

Und los geht´s

Ein neues Node.js Projekt zu starten ist keine große Sache.

1. Visual Studio starten. Im Datei-Menü erst Neu klicken und dann Projekt.

clip_image001

2. Danach auf der linken Seite: Installiert > Vorlagen > JavaScript Menüpunkt aufrufen und rechts Basic Windows Azure Express Application auswählen. Speicherort und Namen für das Projekt bestimmen und OK klicken.

clip_image003

3. In der Folge informiert eine Nachricht darüber, dass in package.json definierte Abhängigkeiten installiert werden müssen, und zwar mithilfe des NPM Paketmanagers. Dieser wird hier genauer erklärt.

clip_image004

4. Nun wird ein Projekt erzeugt, das die Datei app.js enthält. Und hier fangen wir an.

Erklärung von app.js

//
/**
 * Module dependencies.
 */

var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.index);
app.get('/users', user.list);

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

Zeilen 6 bis 10

Die Zeilen 6 bis 10 laden verschiedene Module, einschließlich express, http und path. Besonders interessant sind aber das Modul routes (dazu später mehr) und das user Modul im routes-Ordner.

Zeile 12

In dieser Ziele riefen wir die Funktion express() auf, die unsere App erzeugen wird. Diese App werden wir benutzen, wenn wir einen HTTP Server erstellen wollen. Gleichzeitig wird dieses Objekt alle Eigenschaften unserer Web Applikation enthalten sowie das Mapping zwischen der URL, die bei einem Request übertragen wird, und der Funktion, welche die entsprechende Response abwickelt.

Zeilen 15 bis 17

In diesen Zeilen legen wir verschiedene Einstellungsparameter fest, darunter auf welchem Port der Server läuft (Zeile 15) und in welchem Verzeichnis die HTML Datei-Templates zu finden sind (Zeile 16). In Zeile 17 bestimmen wir die Template-Engine die wir benutzen wollen, in unserem Fall ist es Jade. Jade ist eine weit verbreitete Template-Engine, die das Schreiben von HTML-Code sehr erleichtert, unter anderem weil sie auf spezielle Syntax-Erfordernisse wie spitze Klammern (<>) verzichtet. Wer die Template-Engine so verändern will, dass sie einfach nur HTML ausgibt und nichts weiter, ersetzt die Zeile 17 mit folgendem Code:
app.set(‚view engine‘, ‚html‘);

Zeilen 18 bis 23

In diesen Zeilen legen wir verschiedene Einstellungsparameter fest. Die Bedeutung der einzelnen Parameter ist aus der API Dokumentation ersichtlich. Für dieses Tutorial muss man das aber nicht im Einzelnen wissen.

Zeilen 24 und 25

Diese Zeilen sind insofern interessant, als dass wir hier eine Middleware bestimmen, die Stylus CSS Sheets und HTML bearbeitet. Middleware ist dabei eine Ebene, die automatisch in die Funktionsaufrufe zwischen dem Empfang eines Requests und der Ausgabe einer Response eingefügt wird. In unserem Fall soll Express die Stylus Middleware und die Static Middleware nutzen für alle Requests bei denen die URL einen bestimmten Pfad innerhalb des öffentlichen Ordners unseres Projekts vorgibt. Dafür führen wir keine Request-Funktion für diese URL aus, sondern nehmen server CSS und JavaScript wörtlich.

Zeile 27 bis 30

In diesen Zeilen geben wir an , wie Express mit Fehlern umgeht, falls die Umgebung nicht als „Produktion“, sondern als „Entwicklung“ eingestellt ist. Über diese Zeilen muss man sich keine Gedanken machen.

Zeilen 32 und 33

Hier planen wir schließlich einen URL-Pfad innerhalb eines HTTP Requests zu einer bestimmten Funktion, welche die Response verarbeitet. Darauf kommen wir gleich noch einmal zurück.

Zeilen 35 bis 38

MIt diesen Zeilen erstellen wir einen HTTP Server und bestimmen den Port, zusammen mit einem Callback für den Fall, dass der Server erfolgreich gestartet wurde.

Routing

Routing und wie man es am besten macht – das ist ein oft diskutiertes Thema und eine endgültige Antwort gibt es wohl nicht. Es gibt zahlreiche Module, die das Routing für Express und Node.js realisieren. Jedes hat seine Besonderheiten und speziellen Strukturen, da ist wohl für jeden etwas dabei. Wir arbeiten hier mit der Routing-Engine, die bereits in Express enthalten ist. In app.js hatten wir die Routing-Engine bereits festgelegt, die Route-Module können einfach aus dem Routing-Verzeichnis importiert werden. Die Routes haben wir in den Zeilen 32 und 33 hinzugefügt. Anders gesagt, wir haben die URL im Browser zur Funktion auf dem Server, die den Request bearbeiten soll, gemappt. Diese die Requests bearbeitenden Funktionen befinden sich im Routing-Verzeichnis. Schauen wir uns daher doch gleich mal index.js an.

/*
 * GET home page.
 */

exports.index = function(req, res){
  res.render('index', { title: 'Express' });
};

Ziemlich unscheinbar, aber diese drei Zeilen erledigen tatsächlich eine Menge Arbeit. Zeile 1 fügt der Exportvariable die Funktion index hinzu. Die Exportvariable wird durch Node.js erstellt, und zwar immer dann wenn ein Modul geladen wird, das es ermöglicht, Funktionen und Variablen zu anderen Modulen zu übertragen, in diesem Fall das app.js Modul.
Die Funktion index nimmt zwei Parameter an, req und res. Wie in Teil 1 beschrieben, verwalten der req Parameter die erhaltenen Requests und der res Parameter eine Variable zu der man die Response schreibt. In unserem Fall führen wir in der Response-Variable die Render-Funktion aus, die zwei Parameter annimmt. Da ist zum einen der Parameter, der bestimmt, welche Ansicht (view) genutzt wird (view ist eine Datei im Views-Verzeichnis), eine Dateiendung ist nicht nötig, index wird index.jade. Der zweite Parameter ist ein Daten enthaltenes Objekt, das in das Jade-Template eingefügt werden kann.

Das Index Template

Das index.jade Template ist eine komplett andere Sprache, die jedoch nicht Teil dieses Tutorials ist. Für diese Tutorial-Serie ist HTML-Wissen notwendig und in diesem Fall wird schnell deutlich, dass Jade Templating das Mapping fast immer direkt zu HTML vollzieht.

extends layout

block content
  h1= title
  p Welcome to #{title}

Mit Ausnahme der Keywords “block” und “extends” bedeuten alle anderen Keywords das Gleiche wie in HTML. Dieses Template wird durch Jade Middleware umgewandelt, welches wir in das folgende HTML geladen haben.

<!DOCTYPE html>
<html>
<head>
    <title>Express</title>
    <link rel="stylesheet" href="/stylesheets/style.css">
</head>
  <body>
    <h1>Express</h1>
        <p>Welcome to Express</p>
  </body>
</html>

Deutlich wird, dass der entstandene H1 tag den Wert des Titels enthält, den wir zuvor in der Render-Funktion übergeben haben. Außerdem wurde er, im Einklang mit dem Text, direkt in den p tag eingefügt. Auffällig ist aber auch, dass das entstandene HTML Elemente enthält, die nicht in Jade gemappt wurden. Und genau hier brauchen wir dann auch das Keyword “extends”. Im vorliegenden Fall haben wir die Datei layout.jade erweitert.

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content

Schon bemerkt? Der Ausdruck “block content” erscheint in beiden Dateien. Jade nutzt das, um zu bestimmen, dass dieser HTML-Block genau hierher gehört (in der Datei layout.jade) und genau so aussehen soll (in der Datei index.jade).

In der Datei layout.jade fällt der Link zu einer style.css Datei auf, welche in unserem Ausgangsprojekt offenbar gar nicht existiert. Diese Datei wird durch den style.styl Code erstellt, mithilfe der Stylus Middleware, die wir in app.js eingestellt hatten.

Und schon haben wir’s! So kommen wir von app.js zu einem Routing, das die Response bestimmt und schließlich zu einer Ansicht (view), die angibt wie die Response letztlich aussieht. Man kann die Web App lokal laufen lassen, wenn man die Debug-Taste klickt (ein anderer Browser ist durch das Klicken des Dropdown-Menüs auf der rechten Seite möglich).

clip_image012

Als Erstes wird dann ein Node.js Server gestartet und der Internet Explorer geöffnet, der die root URL anzeigt.

Veröffentlichen über Azure (für alle, die Visual Studio nutzen)

Jetzt haben wir also eine funktionierende Express-basierte Node.js App am Start. Dann ist der nächste Schritt doch, sie auch in der Cloud laufen zu lassen. Dazu braucht es nur ein paar Klicks. Die App kann in jeder Cloud betrieben werden, die Node.js unterstützt. Beispiele sind Nodejitsu, Heroku und Engine Yard. Wir werden hier Microsoft Azure nutzen, weil man dort eine Node.js Website kostenlos laufen lassen kann.

Zur kostenlosen Testversion von Microsoft Azure geht es hier. Damit bekommt man alle Services von Azure bis zu einer Höhe von 150€ gratis. Mit Azure Websites, das wir hier nutzen, kann man bis zu zehn Webseiten kostenlos betreiben.

1. Sobald das Azure-Konto eingerichtet ist, gehen wir zurück zur IDE. Dort führen wir auf unserem Express Projekt einen Rechtsklick aus und wählen im Menü dann „Veröffentlichen“.

clip_image018

2. Das Menü „Veröffentlichen“ öffnet einen Assistenten mit einigen Optionen, wir wählen als Ziel Microsoft Azure Websites.

3. An dieser Stelle erfolgt der Login, und zwar mit dem gleichen Microsoft-Konto wie bei der Azure-Anmeldung.

4. Nun „Neu“ auswählen, um eine neue Azure Webseite zu erstellen. Existiert schon eine, dann einfach diese im Dropdown-Menü auswählen.

http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-29/4532.BLOG-POST-_2D00_-Part-2-_2D00_-Screenshot-12.png

5. Die Felder im Assistenten ausfüllen (siehe unten). Darauf achten, einen unverwechselbaren Namen für die Seite zu wählen und dann „Erstellen“ klicken.

http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-29/7823.BLOG-POST-_2D00_-Part-2-_2D00_-Screenshot-13.png

6. Als Nächstes erscheint ein vorausgefüllter Assistent mit einem Button Veröffentlichen am Ende, diesen dann klicken.

clip_image024

GESCHAFFT! Das Projekt ist in der Azure Cloud veröffentlicht!

Jetzt lohnt es sich, mal ein paar Azure Webseiten im Azure Portal anzusehen. Sehr empfehlenswert ist auch dieses Video.

Wichtiger Tipp: Falls beim Veröffentlichen Probleme auftreten sollten, unbedingt das Projekt näher am Stammverzeichnis platzieren, um kurzzeitige Fehler beim Kopieren zu vermeiden.

clip_image026

clip_image028

Dranbleiben für Teil 3!

Teil 3 (Wie man ein Backend mit Node, Mongo and Socket.IO aufbaut) erscheint bald hier bei Dr.Web. Wer mehr Neuigkeiten dazu und zu anderen Artikeln erfahren will, kann mir einfach auf Twitter folgen: @ramisayar.

Weiteres Wissenswerte zu Node auf Azure

Ausführlichere Lehrinhalte zu Node gibt es in meinem Kurs an der Microsoft Virtual Academy.
Sehr hilfreich auch diese Kurzvideos über ähnliche Node-Themen:

Dieser Artikel ist Teil der Web Dev Tech Series von Microsoft. Wir freuen uns, das Projekt Spartan und seine neue Rendering Engine mit euch zu teilen. Kostenlose Virtual Machines oder Remote Testings für Mac, iOS, Android oder Windows gibt es hier: modern.IE.

Weitere Teile dieser Serie bei MSDN

Part 1 –  Introduction to Node.js
Part 2 – Welcome to Express with Node.js and Azure
Part 3 – Building a Backend with Node, Mongo and Socket.IO
Part 4 – Building a Chatroom UI with Bootstrap
Part 5 – Connecting the Chatroom with WebSockets
Part 6 – The Finale and Debugging Remote Node Apps

(dpe)

Kategorien
JavaScript & jQuery Programmierung

Aus der Praxis: wir bauen eine Chatroom Web-App mit Node.js (Teil 1)

In dieser Node.js Tutorial-Serie zeigen wir, wie man eine Node.js-getriebene Echtzeit-Chatroom Web-App erstellt, die vollständig cloud-fähig ist. Es wird darum gehen, Node.js auf einem Windows-Rechner aufzusetzen (oder, für alle Mac-User, zumindest die Konzepte dahinter zu verstehen), ein Web-Frontend mit Express zu entwickeln, eine Node-Express-App auf Azure zu bringen, wie man Socket.IO nutzt um einen Echtzeit-Layer hinzuzufügen und wie man das Ganze zum Schluss einsetzt. Als Entwicklungsumgebung verwendet das Tutorial das optionale Visual Studio und das Node.js Tools für Visual Studio Plugin — die Links für den kostenlosen Download beider Tools folgen weiter unten.

nodejs-partone-teaser_DE

Schwierigkeitsstufe: Einsteiger bis mittlere Kenntnisse, vorausgesetzt werden HTML5 und JavaScript.

Teil 1 – Einführung in Node.js

Hier nun also der Teil 1 der Praxis-Tutorialserie über Node.js: Wir programmieren eine Node.js-getriebene Chatroom Web App. In diesem Teil erkläre ich was Node.js überhaupt ist, warum man sich unbedingt mit Node.js beschäftigen sollte und wie man es auf dem Rechner einrichtet.

Was ist Node.js… und wofür brauche ich das?

Node.js ist eine Laufzeitumgebung und Bibliothek um JavaScript Applikationen außerhalb des Browsers laufen zu lassen. Node.js wird vor allem dafür benutzt um Server-Applikationen in Echtzeit laufen zu lassen und glänzt in seiner Leistungsfähigkeit durch die Nutzung nicht-blockierender I/O und asynchroner Events. Rund um Node.js ist ein komplettes Web-Ökosystem entstanden, mit mehreren nutzbaren Web App Frameworks und Protokollimplementierungen. Kurz: Es gehört zweifellos zu den einfachsten und schnellsten Tools, um heutzutage Echtzeit-Anwendungen für das Web zu schreiben.

Warum man mit Node.js arbeiten sollte? Ganz einfach: JavaScript. JavaScript ist unglaublich populär und weitverbreitet. Dass das Web zum heutigen dynamischen Wunderland wurde, dazu hat diese Sprache als eine der Hauptantriebskräfte sicher ganz wesentlich beigetragen. Was inzwischen alles innerhalb eines Browsers möglich ist schlägt alles Andere!

JavaScript entstand eigentlich am Frontend — aber dank der V8 JavaScript Engine und der Arbeit von Ryan Dahl kann man heute vernetzte JavaScript Anwendungen außerhalb des Browsers laufen lassen, eben mit dem Ziel Web Apps zu bauen. Node.js hilft die Programmiersprachen die von deiner App genutzt werden, zusammen zu bringen. Es ist keine weitere Sprache für das Backend nötig, JavaScript kann überall genutzt werden. Wer Erfahrungen mit der Programmierung und dem Design von Webseiten hat sowie mit Web App Frontends in HTML, CSS und JavaScript, der braucht keine andere Sprache zu lernen um komplexe, daten-getriebene Backends für Apps zu schreiben.

Node.js spielt zudem eine wesentliche Rolle bei der Weiterentwicklung von WebSockets als eine Methode für die Echtzeit-Kommunikation zwischen Frontend und Backend. Die Nutzung von WebSockets und von Bibliotheken wie Socket I/O, die auf diesem Protokoll aufbauen, haben die Erwartungen daran, was Web-Anwendungen heute leisten sollen nach oben geschraubt. Und uns Entwicklern die Chance gegeben, das Web neu zu denken und zu gestalten.

Node.js in Windows 8 aufsetzen

Wir brauchen zuallererst einen halbwegs aktuellen und frisch konfigurierten Rechner. Und dann kann es losgehen mit der Installation von Node.js auf Windows 8.1.

1. Node.js installieren

Als erstes die Node.js Runtime herunterladen und installieren. Mit dem Windows Installer geht das kinderleicht.

Wer dagegen ein Fan von Chocolatey ist, dem Paketmanager für Windows, kann Node.js folgendermaßen installieren:

choco install nodejs.install

2. Set-up bestätigen

Dann genau hinschauen, ob das Node.js Installationsprogramm zur PATH Systemumgebungsvariable hinzugefügt wurde. Wer wissen will, wie man die Umgebungsvariable in Windows 8 und WIndows 8.1 verändern kann, schaut am besten dieses Video. Der folgende Ordner muss unbedingt zur PATH Variable hinzugefügt worden sein:

C:\Program Files (x86)\nodejs\

Wer bei der Befehlseingabe node –h eingibt, dem sollte die Hilfe-Dokumentation für das Node.js Installationsprogramm angezeigt werden.

Neben Node.js sollte auch NPM, das System welches die Node.js Pakete verwaltet, installiert und über die Befehlseingabe erreichbar sein. Einfach npm –h eingeben, und dann sollte die Hilfe-Dokumenation von NPM angezeigt werden.

Wenn was schiefläuft…

Wenn ein Fehler wie dieser auftreten sollte…:

Error: ENOENT, stat 'C:\Users\someuser\AppData\Roaming\npm'

…sollte man einen Ordner erstellen auf dem oben angegebenen Pfad, siehe auch diese StackOverflow Frage. Dieses Problem tritt nur im aktuellen Node.js Installer auf und sollte mit der nächsten Version beseitigt sein. Der Ordner wird so erstellt:

mkdir -r C:\Users\someuser\AppData\Roaming\npm

Ein Entwicklungswerkzeug auswählen

Nachdem Node.js installiert ist, ist es jetzt an der Zeit ein Entwicklungswerkzeug auszuwählen. Es gibt da kaum Einschränkungen. In den Tutorials werde ich jedoch sowohl Visual Studio nutzen, um die Chat Engine zu entwickeln, zu debuggen und aufzusetzen als auch Node.js Tools for Visual Studio (NTVS) – ein kostenloses Open Source Plugin für Visual Studio, das die Entwicklung von Node.js Anwendungen unterstützt.

Ein neues Node.js Projekt in Visual Studio starten

Hinweis: Die Screenshots zeigen Visual Studio 2013 Ultimate.

Ein neues Node.js Projekt zu starten ist keine große Sache.

1. Visual Studio starten. Im Datei-Menü erst Neu klicken und dann Projekt.

http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-29/0741.BLOG-POST-_2D00_-Part-1-_2D00_-Screenshot-1.png

2. Im Fenster „Neues Projekt“ erst die Menüauswahl Installiert vergrößern, dann Vorlagen, und schließlich JavaScript auswählen. Im Hauptfenster Blank Node.js Web Application wählen. Dann einen Speicherort und einen Namen für das Projekt wählen und OK klicken.

http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-29/3414.BLOG-POST-_2D00_-Part-1-_2D00_-Screenshot-2.png

3. Angezeigt wird der folgende Bildschirminhalt. An dieser Stelle kann man Visual Studio auch erstmal ganz zwanglos ausprobieren und entdecken. Jetzt kann man die erstellte server.js Datei im Solution Explorer öffnen (normalerweise rechts auf dem Bildschirm sichtbar, aber sie kann auch an anderer Stelle auftauchen.)

http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-29/0211.BLOG-POST-_2D00_-Part-1-_2D00_-Screenshot-3.png

4. Jetzt die Node.js Web-Anwendung im favorisierten Browser debuggen.

http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-29/2235.BLOG-POST-_2D00_-Part-1-_2D00_-Screenshot-4.png

“Hello World” in Node.js

Wie in anderen Sprachen auch, zeigt der generierte Beispiel-Code, wie man “Hello World” im Browser anzeigen lassen kann. Nun werde ich erklären wie der erstellte Code in server.js Zeile für Zeile funktioniert.

*Hinweis: Wie oben schon erwähnt, geht diese Serie davon aus, dass Kenntnisse über JavaScript und HTML5 vorhanden sind und man weiß wie HTTP/das Internet funktionieren.

Zeile 1

  var http = require('http');

Node.js besitzt ein einfaches System um Modul und Abhängigkeiten zu laden. Dazu einfach die Funktion “require” mit dem Dateipfad oder dem Verzeichnis, welches das Modul enthält, aufrufen. Daraufhin wird eine Variable zurückgegeben, die alle exportierten Funktionen dieses Moduls enthält.

Zeile 2

var port = process.env.port || 1337;

In dieser Zeile bestimmen wir an welchem Port der HTTP Server, der das HTML ausgibt, laufen soll. Falls eine Portnummer in den Umgebungsvariablen angegeben ist, nehmen wir diese. Ansonsten benutzen wir einfach die 1337.

Zeile 3

http.createServer(function (req, res) {

Wir brauchen einen Server der die HTTP-Anfragen (Requests) bearbeitet. Wir übergeben auch die createServer Funktion, eine Callback-Funktion mit zwei Parametern um jede einzelne Anfrage zu bearbeiten und eine Antwort (Response) zu senden. Wer noch nicht mit Callback-Funktionen in JavaScript gearbeitet hat, dem empfehle ich Michael Vollmers Artikel. Die erhaltene Anfrage wird im req parameter übermittelt und die Antwort solllte an den res parameter gehen.

Zeile 4

res.writeHead(200, { 'Content-Type': 'text/plain' });

Jede HTTP-Response benötigt eine Statuszeile und Headers. Mehr über HTTP Header und wie sie funktionieren gibt es in diesem Artikel. Im vorliegenden Beispiel wollen wir zu 200 OK als Status-Reponse zurück und den Content-Type als einfachen Text festlegen. Dazu rufen wir die writeHead function auf dem Response-Objekt auf.

Zeile 5

res.end('Hello World\n');

Nach dem Schreiben der Response wollen wir die Ende Funktion aufrufen. Wir können auch den endgültigen Inhalt mit der Ende Funktion durchlaufen lassen. In diesem Fall senden wir den String “Hello World” in normalem Text.

Zeile 6

}).listen(port);

Wir sperren den Callback und rufen die listen Funktion am anfangs definierten Port auf. Dadurch wird der Server gestartet, der nun beginnt Requests am festgelegten Port anzunehmen.

Um das Resultat zu sehen, beginnt man nun mit dem Debuggen: Dazu einfach den Button klicken, der im vorigen Screenshot zu sehen war. Nun ist “Hello World” im Browser zu sehen.

http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-29/7652.BLOG-POST-_2D00_-Part-1-_2D00_-Screenshot-5.png

Voilà! Und schon ist eine Node.js App auf Windows 8.1 mithilfe von Visual Studio 2013 zum Laufen gebracht.

Dranbleiben für Teil 2!

Teil 2 — Wie man das “Hello World”-Projekt in die Cloud bringt — ist hier in meinem Blog zu finden. Wer mehr Neuigkeiten dazu und zu anderen Artikeln will, kann mir einfach auf Twitter folgen: @ramisayar.

Weiteres Wissenswerte zu Node auf Azure

Ausführlichere Lehrinhalte zu Node gibt es in meinem Kurs an der Microsoft Virtual Academy.
Sehr hilfreich auch diese Kurzvideos über ähnliche Node-Themen:

Dieser Artikel ist Teil der Web Dev Tech Series von Microsoft. Wir freuen uns, das Projekt Spartan und seine neue Rendering Engine mit euch zu teilen. Kostenlose Virtual Machines oder Remote Testings für Mac, iOS, Android oder Windows gibt es hier: http:// modern.IE.

Weitere Teile dieser Serie bei MSDN

Part 1 – Introduction to Node.js
Part 2 – Welcome to Express with Node.js and Azure
Part 3 – Building a Backend with Node, Mongo and Socket.IO
Part 4 – Building a Chatroom UI with Bootstrap
Part 5 – Connecting the Chatroom with WebSockets
Part 6 – The Finale and Debugging Remote Node Apps