Gruppenkommunikation in Sensornetzwerken (PD Stefan Bosse) |
In dieser Übung soll ein erster Prototyp einer kanalbasierten Sensorkommunikation über Gruppen programmiert werden
Der Sensor Router ermöglicht die Verbidung von Sensorknoten für kanalbasierte Kommunikation.
Der Sensor Router (Program luaosrouter
) stellt folgende Dienste zur Verfügung:
Der Sensor Route nutzt zwei verschiedene Kommunikationsprotokolle:
Welche Nachteile hat diese Kommunikationsarchitektur in Hinblick auf Robustheit und Skalierbarkeit (Anzahl Sensorknoten)?
Es wird benötigt:
> lvm luaosrouter -h
usage: luaosrouter [-v -h] [-host IP/URL/?] [-port NUM] [-portHTTP NUM] [-portWS NUM]
> lvm luaosrouter
# Oder zum Testen
> lvm luaos.out service.lua
Je nach Betriebssystem kann es wichtig sein eine Host IP Adresse anzugeben. Wenn keine IP adresse des Rechners bekannt ist (intern, nicht öffentlich!) dann kann mit -host ?
eine ermittelt werden (kann aber muss nicht richtig sein - kontrollieren!)
-port NUM
verändert werden (der WebSocket Prot ist standardmäßig port+1).Jede Kommunikation mit dem Router und dann auch mit Peers (Sensorknoten) findet über eine Route Instanz statt:
local <route> = route:new(url:string)
Nur der HTTP Port des Routers muss bekannt sein und bei der Ezuegung des Routeobjekts angegeben werden.
local result = <route>:ping()
local <port> = <route>:connect()
local result = <port>:connect(uuid:string,bidirectional:boolen)
Wenn das Argument bidirectional auf false gesetzt wird (oder nicht vorhanden ist) werden nachrichten von diesem Port nur an die Zielknoten gesendet. Die Zielknoten können keine Antwort zurück schicken (da sie noch nicht mit diesem Peer verbunden sind). Wenn das Argument bidirectional auf true gesetzt wird gibt es auch einen Rückkanal.
<port>:write(string|table,destination?:string)
local data,err = <port>:read()
Nachrichten können an alle mittels connect angeschlossenen Peers (Multicast) oder an einen bestimmetn (destination) Peer (Unicast) gesendet werden
Die read Methode ist blockierend, und daher sollte es eine eigene Koroutine für den Empfang geben (alternativ):
local co = coroutine.create(function ()
while <port>.state == "OPEN" do
local data = <port>:read();
-- Process data
end
end)
coroutine.resume(co)
local status = <route>:create(grouip:string)
local members = <router>:ask(groupid:string)
local status = <route>:join(grouid:string,peerid:string)
local status = <route>:unjoin(grouid:string,peerid:string)
Der Router stellt auch einen Garbage Collector Service zur Verfügung. Dieser wird in periodischen Abständen ausgeführt:
Der Garbage Colelctor wird automatisch gestartet.
Eine Koroutine ist ein eigener Kontrollpfad
<port>:read
oder sleep
)
Koroutinen können Schleifen enthalten die zum periodisch ausgeführt werden. Dazu in den Schleifenkörper die blockierende sleep(milli)
Funktion verwenden (oder wie oben die read Opartion des Receivers für einen Kanal)
Vorbereitung: Wähle einen rechner aus auf dem der LuasOS Router läuft. Dann wähle möglich viele Rechner im lokalen oNetzwerk oder über das Internet aus auf den über den Browser und über die Konsole und lvm Skripte ausgeführt werden können.
Welche Netzwerkarchitektur wird in diesem Beispiel erzeugt?
Naiver Ansatz:
Init: Jeder Knoten hat eine ID (UUIDv4) und eine zufällig
erzeugte Priorität im Bereich {0,1,..,65535} (Es kann Dopplung geben!!)
1. Jeder Knoten sendet allen anderen Knoten das Tupel <UUID,PRIO>
als Nachricht "REQ <UUID,PRIO> "
2. Jeder Knoten empfängt in einem Zeitintervall [t0,t1] die
Nachrichten "REQ" beginnend mit der ersten Nachricht
3. Jeder Knoten wählt dann einen Leaderknoten aus wenn es einen einzigen
Knoten mit der größten PRIO gibt
4. Wenn ein Knoten einen Leader ausgewählt hat sendet er eine "ACK" Nachricht
an alle anderen Knoten ("ACK <UUID>")
5. Wenn ein Knoten alle "ACK" Nachrichten erhalten hat steht der Leader fest
6. Ansonsten (nach einer Wartezeit [t1,t2]) startet eine neue Runde bis ein Leader gefunden wurde
Hinweis: Eine Nachricht wird über den Kanal als Tabelle versendet. Z.B. im Format:
local msg = { tag="ACK", id=1234 }
<port>:write(msg)
Programmcode Leaderwahl
▸
|
✗
≡
|
Nachdem der Zeitserver feststeht sollen alle Knoten der Gruppe von dem Zeitserver die Uhrzeit abfragen und damit ihre eigene Uhr synchronisieren (Delta Offset).
Aber: Der Zeitstempel t in einer "TIME" Nachricht kommt immer um einen zeitlichen Versatz t+δ an (Zeit der Nachrichtenübertragung)
Wie könnte man die Zeitdifferenz δ schätzen bzw. hinzurechnen?
Bei der Anfrage wird die eigene Zeit vermerkt, ebenso die Zeit beim Eintreffen der Antwort.
▸
|
✗
≡
|