Open Source im professionellen Einsatz
Linux-Magazin 01/2012
1249

Meminfo-Dienst

Der zu erstellende Dienst Meminfo soll periodisch Daten über die Speicherauslastung des Hosts aus der Datei »/proc/meminfo« auslesen und per Netzwerk zur Verfügung stellen. Der Browser stellt sie mittels Visualize grafisch dar.

Zur Datenübermittlung kommt das Json-Format zum Einsatz. Die Javascript Object Notation (Json, [16]), ist eine der Sprache Javascript entnommene Beschreibung von Objekten. Beispielsweise beschreibt »{"Jahreszeit":"Fr\u0 0fchling","Monate":[" M\u00e4rz","April","Mai"],"Durchschnitt": 8.6}« das Objekt »Frühling« bestehend aus drei Schlüssel-Wert-Paaren. Der Wert des Feldes »Jahreszeit« enthält die Zeichenkette »Frühling« , »Monate« eine Liste von Zeichenketten und der Wert des Feldes »Durchschnitt« die Fließkommazahl »8.6« . Json kodiert Sonderzeichen gemäß Unicode als vierstellige hexadezimale Zahl mit Präfix »\u« .

Beim Umsetzen des Meminfo-Servers mit Autobahn (Listing 9) lassen sich fehlende Funktionen durch den Import von Python-Modulen nachrüsten. Der Websocket-Server »MeminfoServerFactory« leitet sich von der Klasse »WebSocketServerFactory« ab. Diese Klasse enthält die Methode »meminfo()« , die Daten mit dem CSV-Reader aus der Datei »/proc/meminfo« ausliest und in ein so genanntes Dictonary überführt (Zeilen 14 bis 16). Das Programm übersetzt dieses Dictonary in eine Json-formatierte Zeichenkette (Zeilen 17 und 18) und überträgt sie dann mit »sendMessage()« an den verbundenen Client. Nach fünf Sekunden wird die Funktion erneut aufgerufen (Zeile 20).

Listing 9

Meminfo-Server

01 import sys, csv, json
02 from twisted.internet import reactor
03 from autobahn.websocket import WebSocketServerFactory, WebSocketServerProtocol
04
05 class MeminfoServerProtocol(WebSocketServerProtocol):
06
07   def onOpen(self):
08     self.factory.meminfo(self)
09
10 class MeminfoServerFactory(WebSocketServerFactory):
11
12   protocol = MeminfoServerProtocol
13
14   def meminfo(self, client):
15     reader = csv.reader(open('/proc/meminfo'), delimiter=':', skipinitialspace=True)
16     dic=dict()
17     for row in reader:
18       dic[row[0]] = row[1]
19     client.sendMessage(json.dumps(dic))
20     reactor.callLater(5, self.meminfo, client)
21
22 if __name__ == '__main__':
23
24   factory = MeminfoServerFactory()
25   reactor.listenTCP(9000, factory)
26   reactor.run()

Die Klasse »MeminfoServerProtocol« ist ebenfalls eine Ableitung einer Autobahn-Klasse – von »WebSocketServerProtocol« . Diese Klasse definiert Eventhandler analog zur Websocket-Schnittstelle in Javascript. Hier wird nach der Neueröffnung einer Verbindung (»onOpen« ) die Methode »meminfo()« aus der Klasse »MeminfoServerFactory« aufgerufen. Zusätzlich ließen sich noch Eventhandler für die Ereignisse »onMessage« , »onError« oder »onClose« definieren. Die Main-Methode des Python-Programms (Zeile 22) bindet eine Instanz von »MeminfoServerFactory« mit »reactor« an die lokale Rechneraddresse sowie TCP-Port 9000 und startet sie.

Die HTML-Seite zum Abfragen des Dienstes ist in Listing 10 zu sehen. Diese bindet die notwendigen CSS- und Javascript-Ressourcen ein. Im »script« -Bereich des Dokuments startet die Funktion »meminfo()« aus der Datei »js/meminfo.js« die Abfrage. Die Funktion »meminfo()« ist in Listing 11 zu sehen. Sie initialisiert eine Verbindung durch Aufrufen der Funktion »websocket()« .

Listing 10

HTML-5-Seite als Speicher-Monitor

01 <!DOCTYPE HTML>
02 <html>
03 <head>
04   <link rel="stylesheet" href="css/combined.css"/>
05   <script src="js/jquery.min.js"></script>
06   <script src="js/visualize.jQuery.js"></script>
07   <script src="js/meminfo.js"></script>
08   <script>
09     $(document).ready(function() { meminfo() } )
10   </script>
11 </head>
12 <body></body>
13 </html>

Listing 11

Funktion meminfo() fragt Meminfo-Server ab

01 function meminfo(url, cont) {
02   url = url?url:"ws://localhost:9000";
03   var count = 0;
04   var ws = websocket(url);
05
06   if (ws === null) {
07     return null;
08   }
09
10   // Erstellen des Ausgabetabletts
11   ws.onopen = function(e) {
12     $(cont?cont:'body').append('<table id="meminfo" style="float:left" \
13       class="line"><caption>Meminfo von '+url+'</caption><thead>\
14       <tr><td></td><th>MemFree</th><th>Shmem</th>\
15       <th>SwapFree</th></tr></thead><tbody></tbody></table>\
16       <div style="float:left" class="visualize" id="meminfochart"></div>');
17   }
18
19   // Empfangene Daten einfügen
20   ws.onmessage = function(e) {
21     count++; // closure
22     try {
23       var obj = jQuery.parseJSON(e.data);
24       $('#meminfo tbody').append('<tr><th>'+count+'</th>'+
25         $('#meminfo thead th').map(function() { return '<td>'+
26         (Math.round(parseInt(obj[$(this).text()])/1000))+'</td>';}
27       ).get().join('')+'</tr>');
28       if (count > 20) {
29         $('#meminfo tr:eq(1)').remove();
30       }
31     } catch(e) {
32       console.log('Protokoll-Fehler');
33     }
34     $('#meminfochart').empty()
35     $('#meminfo.line').visualize({type: 'line', parseDirection: 'y',
36        'height':'200px', 'width':'500px'}, $('#meminfochart'));
37   }
38 }

Nach erfolgreicher Eröffnung (»onopen« ) hängt der Code dem HTML-Dokument mit der Jquery-Methode »append()« eine leere Tabelle sowie einen Bereich zur Ausgabe des Diagramms an. Beim Eintreffen einer Nachricht (»onmessage« ) übersetzt das Skript die Json-formatierte Zeichenkette in ein Javascript-Objekt. Falls dies gelingt, bekommt die Tabelle eine weitere Zeile aus Werten der Nachricht angehängt. Die Auswahl der Werte aus dem Objekt geschieht durch das Auslesen der Schlüssel aus dem Kopf der Tabelle. Sobald die Tabelle mehr als 20 Zeilen enthält, löscht der Code die jeweils erste Zeile.

Falls die Rückübersetzung der Json-formatierten Zeichenkette fehlschlägt, wird ein Fehler notiert. Abschließend löscht Javascript das bestehende Diagramm und erstellt es neu, indem es die Funktion »visualize()« aufruft. Abbildung 9 zeigt den Meminfo-Client bei der Arbeit.

Ausblick

HTML 5 beschert dem Web eine ganze Reihe von Neuerungen, die es nachhaltig verändern dürften. Das Canvas-Element wird mehr kontextbezogene Grafiken hervorbringen. Websockets bieten eine Schnittstelle zu einer bisher unbekannten Zahl von Diensten. Der in diesem Artikel implementierte Meminfo-Dienst deutet an, wie sich Daten verschiedener Dienste im Web zusammenführen lassen.

Damit geht HTML 5 gut gerüstet in die Zukunft, in der Herausforderungen wie beispielsweise das "Web der Dinge" warten. Auch die weitere Entwicklung von Javascript bleibt spannend. Mit der Ausweitung seiner Schnittstellen auf lokale Ressourcen des Clients entwickeln sich HTML-5-Dokumente zu Bausteinen verteilter Anwendungen weiter. (mhu)

Der Autor

Der Diplom-Physiker Andreas Möller http://pamoller.com beschäftigt sich seit zehn Jahren mit der Entwicklung von Internetsoftware. Dazu zählen Datenbank- und Webanwendungen sowie Arbeiten im Bereich Single Source Publishing. Daneben hat er an Büchern, Lernprogrammen und E-Books mitgearbeitet. Zurzeit ist er als Berater und freier Autor tätig.

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Screencast: Webanwendungen mit Websockets

    In einem Screencast zum Linux-Magazin-Artikel "Blühende Oberflächen" zeigt der Autor Andreas Möller Server- und Client-Komponente für die Anwendung.

  • WebSocket4J 1.2 implementiert Client und Server

    Websocket4J, eine freie Umsetzung des bidirektionalen Websocket-Protokolls in Java, ist in Version 1.2 erhältlich. Erstmals setzt sie neben dem Server auch den Client-Part um.

  • Websockets

    Wer den Raspberry Pi über eine Android-App zum Tanz auffordern möchte, bringt am besten Websockets mit auf den Ball. Sie erleichtern die gepflegte Konversation mit dem graziösen Minirechner.

  • Leserbriefe

    Haben Sie Anregungen, Statements oder Kommentare? Dann schreiben Sie an redaktion@linux-magazin.de. Die Redaktion behält es sich vor, die Zuschriften und Leserbriefe zu kürzen. Sie veröffentlicht alle Beiträge mit Namen, sofern der Autor nicht ausdrücklich Anonymität wünscht.

  • Perl-Snapshot

    HTML 5 bringt Websockets, über die Webserver mit ihren Clients in einen Dialog treten können. Die im Folgenden vorgestellte kleine Webapplikation zeigt in Echtzeit im Browser, welche Seiten beliebige User von einem Webserver im Moment aufrufen.

comments powered by Disqus

Ausgabe 11/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Stellenmarkt

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.