Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
| Ambdós costats versió prèvia Revisió prèvia Següent revisió | Revisió prèvia | ||
|
libgdx_comunicacions [2023/04/18 00:42] enric_mieza_sanchez [Exercicis] |
libgdx_comunicacions [2025/03/18 23:13] (actual) enric_mieza_sanchez [Exercicis] |
||
|---|---|---|---|
| Línia 2: | Línia 2: | ||
| Aquest article ve de [[jocs libGDX]] on implementem jocs multiplataforma. | Aquest article ve de [[jocs libGDX]] on implementem jocs multiplataforma. | ||
| + | |||
| + | libGDX es programa en Java, per tant podriem emprar les llibreries estàndard de comunicació HTTP o WebSockets. Però si utilitzem les pròpies de liBGDX ens facilitarà el codi, ja que ens estalviarem la gestió dels //threads// de comunicació necessaris a [[Android]] explicats a [[Android Threads]]. | ||
| Llibreries de comunicacions: | Llibreries de comunicacions: | ||
| Línia 11: | Línia 13: | ||
| \\ | \\ | ||
| + | ===== Crides HTTP estàndard ===== | ||
| + | |||
| + | Les realitzem mitjançant la [[https:// | ||
| + | |||
| + | ==== Exercicis ==== | ||
| + | |||
| + | <WRAP todo> | ||
| + | Fes un [[https:// | ||
| + | |||
| + | Implementa una crida HTTP a alguna web quan premem un botó del Dialog. | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | \\ | ||
| ===== WebSockets ===== | ===== WebSockets ===== | ||
| Línia 25: | Línia 43: | ||
| --> Arxius de configuració (Gradle, etc.)# | --> Arxius de configuració (Gradle, etc.)# | ||
| - | Afegiu | + | |
| + | Per tal que funcionin | ||
| + | |||
| + | <file xml AndroidManifest.xml> | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | |||
| + | Si volem compilar versió HTML: | ||
| + | |||
| + | <file xml GdxDefinition.gwt.xml> | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | |||
| + | I el més important, configurar els diferents '' | ||
| + | |||
| + | General: | ||
| <file gradle build.gradle> | <file gradle build.gradle> | ||
| allprojects { | allprojects { | ||
| Línia 35: | Línia 70: | ||
| } | } | ||
| } | } | ||
| + | </ | ||
| - | project(" | + | <WRAP tip> |
| - | dependencies { | + | ULL: als segúents només cal afegir la línia del repo de '' |
| - | api "com.github.MrStahlfelge.gdx-websockets: | + | </ |
| - | } | + | |
| - | } | + | |
| - | project(" | + | Core: |
| - | dependencies { | + | <file gradle core/ |
| - | api " | + | dependencies { |
| - | } | + | api " |
| + | implementation | ||
| + | |||
| + | // ... | ||
| } | } | ||
| + | </ | ||
| - | project(" | + | Android: |
| - | dependencies { | + | <file gradle android/ |
| - | api "com.github.MrStahlfelge.gdx-websockets: | + | dependencies { |
| - | | + | // |
| - | | + | |
| - | } | + | |
| - | } | + | |
| - | project(": | + | // ... |
| - | dependencies { | + | |
| - | api "com.github.MrStahlfelge.gdx-websockets: | + | |
| - | } | + | |
| } | } | ||
| </ | </ | ||
| - | < | + | Desktop (Lwjgl3): |
| - | | + | < |
| - | | + | dependencies { |
| + | | ||
| + | implementation "com.badlogicgames.gdx: | ||
| + | | ||
| + | implementation project(': | ||
| + | |||
| + | | ||
| </ | </ | ||
| - | Recordeu també que per tal que funcionin les comunicacions en Android cal activar els permisos adequats: | + | HTML: |
| + | <file gradle html/ | ||
| + | dependencies { | ||
| + | // ... | ||
| + | implementation " | ||
| + | implementation " | ||
| + | implementation " | ||
| + | implementation " | ||
| - | <file xml AndroidManifest.xml> | + | implementation project(': |
| - | < | + | |
| - | < | + | // ... |
| + | } | ||
| </ | </ | ||
| + | |||
| <-- | <-- | ||
| + | |||
| + | També cal que inicialitzem els WebSockets als arxius '' | ||
| + | CommonWebSockets.initiate(); | ||
| \\ | \\ | ||
| Línia 82: | Línia 135: | ||
| * Podem enviar des de qualsevol part del codi inclús des del '' | * Podem enviar des de qualsevol part del codi inclús des del '' | ||
| * Per rebre dades del servidor ho fem mitjançant l' | * Per rebre dades del servidor ho fem mitjançant l' | ||
| + | |||
| + | <WRAP important> | ||
| + | El protocol WebSockets < | ||
| + | |||
| + | La variable '' | ||
| + | |||
| + | <code java> | ||
| + | socket = WebSockets.newSocket(WebSockets.toSecureWebSocketUrl(address, | ||
| + | </ | ||
| + | |||
| + | </ | ||
| <file java GameScreen.java> | <file java GameScreen.java> | ||
| + | import com.github.czyzby.websocket.WebSocketListener; | ||
| + | import com.github.czyzby.websocket.WebSocket; | ||
| + | |||
| class GameScreen extends Screen { | class GameScreen extends Screen { | ||
| WebSocket socket; | WebSocket socket; | ||
| Línia 95: | Línia 162: | ||
| address = " | address = " | ||
| socket = WebSockets.newSocket(WebSockets.toWebSocketUrl(address, | socket = WebSockets.newSocket(WebSockets.toWebSocketUrl(address, | ||
| + | // ULL: si és a traves de HTTPS , el protocol seria wss enlloc de ws | ||
| + | //socket = WebSockets.newSocket(WebSockets.toSecureWebSocketUrl(address, | ||
| socket.setSendGracefully(false); | socket.setSendGracefully(false); | ||
| socket.addListener((WebSocketListener) new MyWSListener()); | socket.addListener((WebSocketListener) new MyWSListener()); | ||
| Línia 129: | Línia 198: | ||
| @Override | @Override | ||
| public boolean onMessage(WebSocket webSocket, String packet) { | public boolean onMessage(WebSocket webSocket, String packet) { | ||
| - | System.out.println(" | + | System.out.println(" |
| return false; | return false; | ||
| } | } | ||
| Línia 135: | Línia 204: | ||
| @Override | @Override | ||
| public boolean onMessage(WebSocket webSocket, byte[] packet) { | public boolean onMessage(WebSocket webSocket, byte[] packet) { | ||
| - | System.out.println(" | + | System.out.println(" |
| return false; | return false; | ||
| } | } | ||
| Línia 153: | Línia 222: | ||
| Podem emprar la [[https:// | Podem emprar la [[https:// | ||
| - | | ||
| - | --> Servidor HTTP + WebSockets amb NodeJS# | ||
| Ens caldrà crear un projecte NodeJS i instal·lar les llibreries: | Ens caldrà crear un projecte NodeJS i instal·lar les llibreries: | ||
| Línia 160: | Línia 227: | ||
| $ cd ws1 | $ cd ws1 | ||
| $ npm init | $ npm init | ||
| - | $ npm install http ws | + | $ npm install http ws express uuid |
| Afegeix '' | Afegeix '' | ||
| $ node index.js | $ node index.js | ||
| - | Cal indicar el projecte com a " | + | |
| - | <file javascript package.json> | + | --> Exemple 1: WebSockets simple# |
| - | { | + | |
| - | " | + | |
| - | " | + | |
| - | ... | + | |
| - | } | + | |
| - | </ | + | |
| <file javascript index.js> | <file javascript index.js> | ||
| - | import | + | const { createServer } = require(' |
| - | import | + | const { WebSocketServer } = require(' |
| const server = createServer(); | const server = createServer(); | ||
| Línia 201: | Línia 262: | ||
| }); | }); | ||
| + | </ | ||
| + | <-- | ||
| + | |||
| + | |||
| + | |||
| + | --> | ||
| + | |||
| + | <file javascript index, | ||
| + | const express = require(' | ||
| + | const http = require(' | ||
| + | const WebSocket = require(' | ||
| + | |||
| + | const app = express() | ||
| + | const httpServer = http.createServer(app); | ||
| + | const wss = new WebSocket.Server({ server: httpServer }) | ||
| + | |||
| + | const { v4: uuidv4 } = require(' | ||
| + | const port = 8888 | ||
| + | var clients = {} | ||
| + | |||
| + | // HTTP ROUTES | ||
| + | app.use(express.static(' | ||
| + | app.get('/', | ||
| + | |||
| + | |||
| + | // WS client connections | ||
| + | wss.on(' | ||
| + | var userid = uuidv4(); | ||
| + | console.log(' | ||
| + | clients[userid] = { " | ||
| + | ws.send(" | ||
| + | // TODO: crear totems i actualitzar | ||
| + | |||
| + | ws.on(' | ||
| + | delete clients[userid]; | ||
| + | // TODO: esborrar totems? | ||
| + | }) | ||
| + | |||
| + | ws.on(' | ||
| + | |||
| + | ws.on(' | ||
| + | try { | ||
| + | // exemple per descoficar JSON | ||
| + | var posData = JSON.parse(data); | ||
| + | posData.id = userid; | ||
| + | console.log(' | ||
| + | // retransmetem posició a tothom | ||
| + | broadcast(JSON.stringify(posData)); | ||
| + | } catch (e) { | ||
| + | console.log(" | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | }); | ||
| + | |||
| + | |||
| + | // SERVER START | ||
| + | httpServer.listen(port, | ||
| + | function appListen () { | ||
| + | | ||
| + | } | ||
| + | |||
| + | // HTTP | ||
| + | ///////////////////////////////// | ||
| + | async function root(req, | ||
| + | res.send(" | ||
| + | } | ||
| + | |||
| + | |||
| + | // WS : Web Sockets | ||
| + | ///////////////////////////////// | ||
| + | async function broadcast (obj) { | ||
| + | for( var id in clients ) { | ||
| + | var client = clients[id]; | ||
| + | //if (client.readyState === WebSocket.OPEN) { | ||
| + | var messageAsString = JSON.stringify(obj) | ||
| + | client.ws.send(obj); | ||
| + | //} | ||
| + | } | ||
| + | } | ||
| </ | </ | ||
| <-- | <-- | ||
| Línia 208: | Línia 349: | ||
| ==== Exercicis ==== | ==== Exercicis ==== | ||
| <WRAP todo> | <WRAP todo> | ||
| - | Implementa el servidor NodeJS | + | **Servidor i app de prova en local** |
| + | |||
| + | Implementa el servidor NodeJS | ||
| + | |||
| + | Fes una aplicació libGDX que connecti amb el servidor i envii la posició on fas un //touch// en la pantalla. Per no saturar de missatges repetitius (i innecessaris), | ||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | **Servidor WebSockets en producció** | ||
| + | |||
| + | Implementa el servidor NodeJS al teu servidor públic (Proxmox). | ||
| + | |||
| + | Ajusta l' | ||
| + | |||
| + | Pots mirar de posar en producciò el servidor NodeJS amb el [[https:// | ||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | **Incorporant websockets a un joc** | ||
| - | Afegeix la llibreria de WebSockets al teu joc libGDX i fes que envii la posició del nostre | + | Afegeix la llibreria de WebSockets al teu joc libGDX i fes que envii la posició del personatge 1 cop per segon. |
| Assegura' | Assegura' | ||