Als Einstieg für ein React-Native-Programm dient immer die default class. Das ist die einzige Klasse, die ein solches Programm automatisch aufruft. Alle weiteren Klassen sprechen Sie aus dieser heraus an. Wie erwähnt, gibt das Tutorial hier einen sehr guten Einblick in die Technik.
Listing 4 beinhaltet den Code für das Frontend. Zu Beginn importiert es die benötigten Komponenten. Danach kommt die default class App, die sich von React.Component ableitet. Der Konstruktor der Klasse App initialisiert eine Variable für den Status der LED und baut die Verbindung zum Web-Socket-Server auf. Achten Sie darauf, die IP-Adresse des Servers anzupassen.
Listing 4
# App.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {led: 0};
this.socket = new WebSocket('ws://192.168.3.185:8000/');
}
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>GPIO Connector</Text>
<Text>{'\n\n'}</Text>
<Button type="outline"
onPress={ () =>
{
this.socket.send("Klick");
this.socket.onmessage = ({data}) => this.setState({led: data});
console.log(this.state.led);
}
}
title="Toggle LED"/>
<Text>{'\n\n'}</Text>
<Text style={styles.text}>{this.state.led}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#00ff00',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize:36,
color:'black',
},
Jede React Native Component hat eine Methode render(), deren Rückgabewert der Server im vorliegenden Fall an das Smartphone leitet. Sie dürfen die Components ineinander verschachteln, jede Komponente darf also weitere Komponenten enthalten.
Die Button-Komponente hat eine Methode onPress. Darin läuft der Code, der nötig ist, um eine Nachricht an den Server zu schicken. Im vorliegenden Fall ist es der Text “Klick”, den der Server allerdings nicht auswertet. Die nächste Zeile speichert die Antwort des Servers in der Variablen led. Die App zeigt den Wert dieser Variablen dann in der <Text>-Komponente nach dem Button an.
Die nächste Zeile gibt die Antwort des Servers auf der Konsole aus. Das ist gerade beim Debuggen sehr hilfreich. Mehr braucht es nicht, um eine Nachricht zu verarbeiten. Ganz am Ende des Programms sind die Styles definiert, die zum Einsatz kommen.
Sobald Sie die Datei anpassen und speichern, übersetzt React Native sie und überträgt sie auf das Smartphone. Das ermöglicht ein schnelles Entwickeln direkt auf dem Zielgerät.
Gegenstelle
Das Design einer App stellt aber nur einen Aspekt einer guten Anwendung dar. Die App sollte ja in irgendeiner Weise Daten erhalten oder mit anderen Anwendungen kommunizieren, wie etwa einer Datenbank. Dazu kommen aktuell häufig Web-Sockets zum Einsatz. Sie bieten eine Möglichkeit, mit geringem Aufwand Daten über das Internet zu übertragen. Im vorliegenden Fall liegt die Aufgabe des Servers darin, den Status einer Leuchtdiode zu verändern. Das erfordert den Transfer von Daten.
Prinzipiell stehen Sockets in vielen Programmiersprachen bereit. Im Beispiel übernimmt der Socket-Server des Node.js-Frameworks die Implementation. Das liegt nahe, da das Frontend der Anwendung mit React Native gebaut ist. Beide Frameworks basieren auf Javascript, also derselben Programmiersprache.
Damit der Server korrekt arbeitet, benötigen Sie noch zwei zusätzliche Module (Listing 5). Das Modul websocket bringt alles mit, was Sie benötigen, um entsprechende Sockets zu programmieren. Das zweite Modul, onoff, stellt eine einfache Möglichkeit bereit, um auf die GPIO des Raspberry Pi zuzugreifen.
Listing 5
$ npm install websocket $ npm install onoff
Die Software arbeitet relativ einfach: Sobald Sie sie aufrufen, liest sie den Status der LED am GPIO-Port 4 (nach BCM-Notation) aus und ändert ihn: Aus 0 macht sie 1 und umgekehrt. Auf diese Weise schaltet der Server jedes Mal, wenn er eine Nachricht vom Client erhält, den Status der LED um. Er übermittelt außerdem den aktuellen Status zurück an den Client. Abbildung 4 zeigt den Versuchsaufbau mit Smartphone.
Listing 6 zeigt, was der Server genau macht. Im ersten Block werden alle nötigen Bibliotheken eingebunden und die GPIO für die Ausgabe konfiguriert. Als Nächstes kommen die Zeilen, die den HTTP-Server definieren, der als Basis für den Web-Socket-Server dient. Der nächste Block enthält dann die Methode, die der Server aufruft, sobald eine Nachricht eintrifft. Sie prüft, ob es sich um UTF8-kodierten Text handelt, und schaltet die LED um.
Listing 6
# server.js
var websocket = require('websocket').server;
var http = require('http');
var Gpio = require('onoff').Gpio;
var LED = new Gpio(4,'out');
var httpServer = http.createServer(function(request, response) {});
httpServer.listen(8000, function() {});
websocketServer = new websocket({ httpServer: httpServer });
websocketServer.on('request', function(request) {
var connection = request.accept(null, request.origin);
connection.on('message', function(message) {
if (message.type === 'utf8') {
if (LED.readSync() === 0) {
LED.writeSync(1);
} else {
LED.writeSync(0);
}
connection.sendUTF(LED.readSync());
}
});
connection.on('close', function(connection) {});
});
An dieser Stelle käme bei einer produktiv genutzten Anwendung erheblich mehr Logik zum Zug. Im letzten Teil könnten zudem Funktionen zum Aufräumen oder Verarbeiten Platz finden, die erst starten, sobald die Verbindung geschlossen wird. Um den Server zu starten, geben Sie einfach das Kommando node server.js ein.






