Web-1/Server state

Uit Inf2019
Naar navigatie springen Naar zoeken springen
De printervriendelijke versie wordt niet langer ondersteund en kan weergavefouten bevatten. Werk uw browserbladwijzers bij en gebruik de gewone afdrukfunctie van de browser.
Web1
Netwerken

Zie ook Regels en richtlijnen
Zie ook Artikelen bewerken

Server state

In het vorige hoofdstuk hebben we gezien hoe je een formulier maakt en verwerkt in de bijbehorende response, via een HTTP POST-flow. Een volgende uitdaging is om de gegevens van een POST ook in de volgende responses te verwerken. Dit betekent dat je de gegevens uit een POST-request in de server moet bijhouden, als onderdeel van de toestand van de server. Hiervoor hebben je verschillende mogelijkheden; we beginnen hier met de eenvoudigste. In latere lessen zullen we andere mogelijkheden onderzoeken.

Als eenvoudig voorbeeld gebruiken we een teller die het aantal requests bijhoudt. Als opstapje daarvoor gebruiken we in plaats van een http-flow, een inject/debug flow.

NodeRed contexten

In een functie-knoop kunnen we de de toestand over verschillende aanroepen bijhouden in een context. Er zijn verschillende soorten context:

  • de node-context (context): deze is alleen toegankelijk in de node zelf;
  • de flow-context (flow): deze in toegankelijk in alle nodes van dezelfde flow (pagina);
  • de globale context (global): deze is toegankelijk in alle nodes.

We kunnen een (naam-waarde)-paar in een context vastleggen met set(naam, waarde). De waarde bij een naam kunnen we weer opvragen met get(naam). Voorbeeld:

  • flow.set("count", reqcount);
  • reqcount = flow.get("count")

Zie: https://nodered.org/docs/writing-functions#flow-context

We kunnen nu de volgende flow maken:

Counter in NodeRed

De functie-node heeft daarbij de volgende inhoud:

var count = flow.get("count") || 0;
count = count + 1;
flow.set("count", count);
msg.payload = count;
return msg;

Opmerking. Voor de "get" van een context-variabele gebruiken we meestal een constructie als flow.get("name") || 0. Dit zorgt ervoor dat we een gedefinieerde waarde krijgen als de variabele in de flow nog niet gedefinieerd is. 0 is in dit geval de initiële waarde.

Opmerking: bij het stoppen van de NodeRed-server gaan deze contexten verloren. In een volgend hoofdstuk gebruiken we een database, om dergelijke waarden op een persistente manier op te slaan.

Opdracht

  • maak een nieuwe flow-pagina aan
  • maak daarop deze flow
  • test de flow, door meerdere malen op "inject" te klikken
    • in de debug-output moet je dan een steeds verder toenemende waarde zien
  • kopieer deze flow op dezelfde pagina: je hebt deze dan dubbel;
  • test deze dubbele flow: het resultaat moet toenemen, welke van de twee je ook gebruikt.

Een eenvoudige request-teller

Visit count in NodeRed

NodeRed-code: /Nodered-visitcount

  • maak een http-flow (http-request => function => template => http-response)
  • configureer de request-node met de URL: /count
  • configureer de function-node met de onderstaande inhoud.
  • configureer de template-node met de onderstaande inhoud.
  • test deze flow via de browser.

function node:

var visits = flow.get("count") || 0;
visits = visits + 1;
flow.set("count", visits);
msg.visitcount = visits;
return msg;

template node:

This is visit number: {{visitcount}}!

Opdracht

  • maak deze deel-flow (op dezelfde pagina);
  • test deze deel-flow
  • ga na dat je de "count" variabele nu zowel via de http-flow als via de inject-flow kunt ophogen.
  • voeg een extra test-flow toe, voor het terugzetten van de teller:
    • inject => function "reset-count", met als body:
    • flow.set("count", 0);
    • een dergelijke test-flow is ook voor de komende opdrachten handig.

Reset count-flow

Bijhouden van de ingelogde gebruikers

Als laatste opdracht in deze les gebruiker we de context-variabelen voor het bijhouden van de lijst van ingelogde gebruikers. Als uitgangspunt gebruiken we de flow van het vorige hoofdstuk. We breiden het page-template uit: hierin gebruiken we de context-variabele flow.users.

Website met login(1)

We voegen het volgende onderdeel toe aan het page-template (boven het nav-element):

<div>
    Users: {{flow.users}}
</div>

De functie process-login-form voegt de naam van de ingelogde gebruiker toe aan de lijst:

var users = flow.get("users") || "";
users = users + " " + msg.payload.username;
flow.set("users", users);
msg.pagetitle = "Welkom";
return msg;

Opdracht

  1. kopieer de flow van het vorige hoofdstuk op een nieuwe flow-pagina (eventueel via Web-1/HTML_formulieren/NodeRed-login-1);
  2. hernoem deze pagina tot Login-2;
  3. schakel de vorige pagina (Login-1) uit;
  4. breng de bovenstaande wijzigingen aan;
  5. test deze flow (zo mogelijk met meerdere browsers).

Vragen en opdrachten

  • kun je deze techniek ook gebruiken om de naam van de lokaal ingelogde gebruiker in de pagina te laten zien?
    • hint: is de lokaal ingelogde gebruiker altijd de laatste naam in de lijst van ingelogde gebruikers?
  • is de lijst met ingelogde gebruikers altijd actueel?
    • hint: hoe krijg je de actuele lijst te zien?