Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
ksk_ef:web:apps:server [2024-08-11 11:04] hofksk_ef:web:apps:server [2024-08-11 11:20] (aktuell) hof
Zeile 111: Zeile 111:
 <code javascript app.js> <code javascript app.js>
 import {TicTacToe} from './tictactoe.js' import {TicTacToe} from './tictactoe.js'
 +
 +let the_game = new TicTacToe();
 +
 +app.get('/game/:gameid', (req, res) => {
 +    return the_game.toJson();
 +})
 +
 +app.get('/set/:gameid/:cell', (req, res) => {
 +    the_game.set(req.params['cell'])
 +    res.json(the_game.toJson())
 +})
 +</code>
 +
 +Nun sollte unser Server ein einziges Game betreiben. Der Zustand sollte unter http://localhost:3000/game/0 zurückgeliefert werden. Ein Spielzug wird über das `set` API gemacht, z.B. sollte das mittlere Feld mit http://localhost:3000/set/0/4 gesetzt werden können. Kannst du (ganz ohne Grafik, nur mit den obigen URLs) ein Spiel spielen?
 +
 +Was gibt es noch zu lösen?
 +  * Der Browser benötigt auch Javascript. Der Click-Handler jedes Buttons soll das `set` API aufrufen und anschliessend den Inhalt des HTMLs an den Spielzustand anpassen.
 +  * Wie weiss der Browser, ob er `X` oder `O` ist?
 +  * Wie können mehrere Spiele betreut werden (Hinweis: schau dir die `gameid` oben an...!)
 +
 +### Client-Side Javascript
 +Der Browser benötigt auch Javascript. Der Click-Handler jedes Buttons soll das `set` API aufrufen und anschliessend den Inhalt des HTMLs an den Spielzustand anpassen.
 +
 +<code javascript tictactoe_client.js>
 +class Tictactoe_Client {
 +   game_id = 0;  // TODO set when joining game
 +   /**
 +     * Fetches the game state, updates the UI, and installs click handlers.
 +     */
 +    async init() {
 +        let i = 0;
 +        for (const button of this.view.grid.getElementsByTagName("button")) {
 +            const cell = i;
 +            button.addEventListener('click', () => {
 +                this.handleJsonUrl(`/set/${this.game_id}/${cell}`);
 +            });
 +            i++;
 +        }
 +    }
 +
 +    /**
 +     * Fetches the given URL and updates the internal state from the parsed JSON.
 +     
 +     * Keeps polling for updates if the updated state could change remotely.
 +     
 +     * @param {string} url the URL to fetch that will return tictactoe JSON.
 +     */
 +    async handleJsonUrl(url) {
 +        let response = await fetch(url);
 +        if (!response.ok) {
 +            let error =  await response.text();
 +            console.log("Error: " + error);
 +            return;
 +        }
 +        const json = await response.json();
 +        this.updateHtml(json);
 +    }
 +    
 +    /** Update the HTML based on JSON game state. */
 +    updateHtml(json) {
 +        let i = 0;  
 +
 +        for (const button of this.grid.getElementsByTagName("button")) {
 +            const cellText = json.grid[i];
 +            // Set the data-state attribute which drives CSS formatting.
 +            button.setAttribute('data-state', cellText);
 +            // Set the text contents of the cell.
 +            button.textContent = cellText;
 +            i++;
 +        }
 +    }
 +}
 </code> </code>
  
Zeile 152: Zeile 224:
 }) })
 </code> </code>
 +
 +### Hinweise
 +
 +  * Die ganze Web-App mit JS & Node: https://github.com/tkilla77/ksr_tictactoe/tree/server_side_js
 +  * Alternative mit Python & Flask auf der Serverseite: https://github.com/tkilla77/ksr_tictactoe/tree/security
  • ksk_ef/web/apps/server.1723374259.txt.gz
  • Zuletzt geändert: 2024-08-11 11:04
  • von hof