Webkrauts Logo

Webkrauts Webkrauts Schriftzug

- für mehr Qualität im Web

Wenn’s mal wieder schneller gehen muss …

Client-Server-Kommunikation mit Socket.io

Wenn’s mal wieder schneller gehen muss …

Will man Informationen möglichst in Echtzeit zwischen Client und Server austauschen, kann das Nachladen von Inhalten in Intervallen mittels Ajax zu unpraktisch sein. Eine einfache, aber vielseitig einsetzbare Methode bietet Socket.io.

Um Informationen auf einer Webseite zu aktualisieren, gibt es typischerweise drei unterschiedliche Vorgehensweisen:

  • Vollständiger Reload der Seite
  • Nachladen von Inhalten mittels Ajax
  • regelmäßige Abfrage in Intervallen (Polling)

All diese Methoden haben ihre Berechtigung, werden aber spätestens dann unpraktisch, wenn Informationen möglichst schnell zu Verfügung müssen oder mehrere Clients über einen Server miteinander kommunizieren. Wäre es nicht von Vorteil, ein Event-System für Client/Server-Kommunikation zu haben, wie es auch aus dem DOM heraus bereits bekannt ist?

Hier kommen WebSockets ins Spiel, ein auf TCP basierendes Netzwerkprotokoll, das parallel zur HTTP-Anfrage des Browsers eine weitere Verbindung zum Server herstellt, die für die gesamte Dauer des Seitenbesuchs permanent bestehen bleibt. Da es auch hier – wie so oft in der Browserwelt – unterschiedliche Implementierungsstände gibt, hilft das Framework http://socket.io. Es setzt auf unterschiedliche Transportmethoden, um eine möglichst große Kompatibilität herzustellen. Damit läuft die Kommunikation unter Internet Explorer 5.5+, Safari 3+, Google Chrome 4+, Firefox 3+, Opera 10.61+, iOS Safari und Webkit auf Android und WebOS.

Praktische Anwendungsfälle

Es gibt viele unterschiedliche Anwendungsmöglichkeiten für Socket.io, die sich in der Regel in vier Bereiche unterteilen lassen:

  1. Benachrichtigung
    Alle serverseitigen Prozesse, die eine längere Laufzeit haben, sollten dem User ein regelmäßiges Feedback geben. Eine weit verbreitete Anwendung ist etwa der Upload von mehreren Dateien oder die Prozessierung von Daten. Hier lassen sich der aktuelle Fortgang der Bearbeitung und eventuelle Fehler direkt kommunizieren.
    So verwendet beispielsweise der Service log.io Benachrichtigungen mit Socket.io zum Real-Time-Monitoring von Serverlogfiles im Browser.

  2. Kommunikation
    Nachrichten lassen sich (z.B. in einem Chat) schnell und mit geringer Serverlast versenden, da nur dann eine Aktualisierung stattfindet, wenn diese erforderlich ist. Es lassen sich sowohl einzelne Clients, Gruppen (über Namespaces in den Event-Namen) als auch alle verbundenen Clients (Broadcast über io.sockets.emit()) mit Nachrichten versorgen.

  3. Spiele
    Ebenfalls bietet sich Socket.io für Online-Spiele an, um beispielsweise Position von Spielfiguren oder einzelnen Einheiten zu synchronisieren.

  4. Steuerung
    Nicht zuletzt lassen sich mit dieser Technik beliebige Dienste steuern, bis hin zu einem angeschlossenen Microcontroller, der Sensordaten liefert oder Motoren ansteuert.

Installation

Socket.io setzt auf Node.js als serverseitigem Framework auf. Nachdem der entsprechende Installer für seine Plattform heruntergeladen und ausgeführt wurde, muss ein beliebiges Verzeichnis für ein neues Projekt angelegt und darin über die Konsole npm install socket.io aufgerufen werden, um Socket.io selbst zu installieren.

Wer Socket.io mit anderen serverseitigen Plattformen nutzen möchte, kann zu einer der zahlreichen Portierungen greifen, die es unter anderem für Java, C++, Perl, Python, Ruby aber auch für Android und Objective-C (iOS) gibt.

Hello world

Wie funktioniert nun die Kommunikation zwischen Client und Server mit Socket.io? Für einen ersten Test benötigen wir dazu nur zwei kurze Stücke JavaScript (GitHub Gist), zuerst für den Server (server.js):

  1. // Kleiner HTTP-Server auf Port 8080
  2. var app = require('http').createServer(serveStaticIndex).listen(8080);
  3.  
  4. // Laden von Socket.io
  5. //(Gibt für die Demo nur Fehler/Warnungen auf der Konsole aus)
  6. var io = require('socket.io').listen(app).set('log level', 1);
  7.  
  8. // Zugriff auf das Dateisystem (zum Ausliefern der index.html)
  9. var fs = require('fs');
  10.  
  11. // Liefert die Startseite aus
  12. function serveStaticIndex(req, res) {
  13.   var fileStream = fs.createReadStream(__dirname + '/index.html');
  14.       res.writeHead(200);
  15.       fileStream.pipe(res);
  16. }
  17.  
  18. // Socket.io-Events
  19. io.sockets.on('connection', function (socket) {
  20.   console.log('[socket.io] Ein neuer Client (Browser) hat sich verbunden.\n');
  21.  
  22.   console.log('[socket.io] SENDE "welcome"-Event an den Client.\n');
  23.   socket.emit('welcome', "Hello world");
  24.  
  25.   socket.on('user agent', function (data) {
  26.     console.log('[socket.io] EMPFANGE "user agent"-Event vom Client:');
  27.     console.log(data, '\n');
  28.   });
  29. });

Und dann eine HTML-Seite (index.html), die wir im Browser aufrufen:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.   <title>Socket.io Test</title>
  5.  
  6.   <!-- Dieses Script wird von Socket.io automatisch zu Verfügung gestellt -->
  7.   <script src="/socket.io/socket.io.js"></script>
  8.  
  9.   <script>
  10.     // Mit dem Socket.io-Server verbinden
  11.     var socket = io.connect('http://localhost');
  12.  
  13.     // Warten auf Nachrichten
  14.     socket.on('welcome', function (data) {
  15.       console.log('[socket.io] "welcome"-Event vom Server empfangen:\n' + data);
  16.  
  17.       // Eigenen Event vom Client an den Server schicken
  18.       socket.emit('user agent', navigator.userAgent);
  19.     });
  20.   </script>
  21. </head>
  22.  
  23. <body>
  24. </body>
  25.  
  26. </html>

Das ist eigentlich schon der gesamte Code, der benötigt wird. Um das Beispiel auszuprobieren, muss der Server mit node server.js gestartet werden. Anschließend kann die Seite dann über http://localhost:8080/ aufgerufen werden. Die Konsole des Browsers und der Kommandozeilenausgabe im Terminal zeigen daraufhin die Nachrichten an, die zwischen Client und Server übermittelt werden: Sobald die Seite im Browser aufgerufen wird, erhält der Server darüber eine Benachrichtigung und sendet seinerseits eine Willkommensnachricht zurück an den Client, der daraufhin seinen User Agent-String als Beispiel wieder an den Server zurückschickt.

socket.on(, function(){}) wartet auf einen Event und reagiert auf ihn, socket.emit(, ) löst einen Event aus. Beides funktioniert auf Client und Server identisch. Soll hingegen eine Nachricht an alle angeschlossenen Clients versendet werden, nutzt man stattdessen io.sockets.emit().

Als Standard-Events gibt es connection, disconnect und message, darüber hinaus können beliebige Namen für Events verwendet werden.

Fazit

Socket.io bietet ein einfaches, eventbasiertes System für Echtzeitbenachrichtigungen. Dank der breiten Browserunterstützung lässt es sich für vielfältige Anwendungen einsetzen.

Die Kommentare sind geschlossen.