bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


libgdx_comunicacions

Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

Ambdós costats versió prèvia Revisió prèvia
Següent revisió
Revisió prèvia
libgdx_comunicacions [2023/04/18 14:28]
enric_mieza_sanchez [Configuració]
libgdx_comunicacions [2024/05/03 17:47] (actual)
enric_mieza_sanchez [Ús en app libGDX]
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 14: Línia 16:
  
 Les realitzem mitjançant la [[https://libgdx.com/wiki/networking|llibreria Networking de libGDX]] que ja ve integrada al propi //framework//. Les realitzem mitjançant la [[https://libgdx.com/wiki/networking|llibreria Networking de libGDX]] que ja ve integrada al propi //framework//.
 +
 +==== Exercicis ====
 +
 +<WRAP todo>
 +Fes un [[https://stackoverflow.com/questions/33062574/how-to-properly-implement-a-dialog-box-using-libgdx|projecte libGDX amb Dialog com el de l'exemple]].
 +
 +Implementa una crida HTTP a alguna web quan premem un botó del Dialog.
 +
 +</WRAP>
 +
 +
  
 \\ \\
Línia 30: Línia 43:
  
 --> Arxius de configuració (Gradle, etc.)# --> Arxius de configuració (Gradle, etc.)#
-Afegiu les següent línies a les seccions adequades:+ 
 +Per tal que funcionin les comunicacions en Android cal activar els permisos adequats: 
 + 
 +<file xml AndroidManifest.xml> 
 +    <uses-permission android:name="android.permission.INTERNET" /> 
 +    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
 +</file> 
 + 
 +Si volem compilar versió HTML: 
 + 
 +<file xml GdxDefinition.gwt.xml> 
 +  <inherits name='com.github.czyzby.websocket.GdxWebSocketGwt' /> 
 +  <inherits name='com.github.czyzby.websocket.GdxWebSocket' /> 
 +</file> 
 + 
 +I el més important, ''build.gradle'' general del projecte (n'hi ha d'altres dins de cada plataforma): 
 <file gradle build.gradle> <file gradle build.gradle>
 allprojects { allprojects {
Línia 43: Línia 72:
 project(":desktop") { project(":desktop") {
     dependencies {     dependencies {
-        api "com.github.MrStahlfelge.gdx-websockets:common:$wsVersion"+        implementation "com.github.MrStahlfelge.gdx-websockets:common:$wsVersion"
     }     }
 } }
Línia 49: Línia 78:
 project(":android") { project(":android") {
     dependencies {     dependencies {
-        api "com.github.MrStahlfelge.gdx-websockets:common:$wsVersion"+        implementation "com.github.MrStahlfelge.gdx-websockets:common:$wsVersion"
     }     }
 } }
Línia 55: Línia 84:
 project(":html") { project(":html") {
     dependencies {     dependencies {
-        api "com.github.MrStahlfelge.gdx-websockets:core:$wsVersion:sources" +        implementation "com.github.MrStahlfelge.gdx-websockets:core:$wsVersion:sources" 
-        api "com.github.MrStahlfelge.gdx-websockets:html:$wsVersion" +        implementation "com.github.MrStahlfelge.gdx-websockets:html:$wsVersion" 
-        api "com.github.MrStahlfelge.gdx-websockets:html:$wsVersion:sources"+        implementation "com.github.MrStahlfelge.gdx-websockets:html:$wsVersion:sources"
     }     }
 } }
Línia 63: Línia 92:
 project(":core") { project(":core") {
     dependencies {     dependencies {
-        api "com.github.MrStahlfelge.gdx-websockets:core:$wsVersion"+        implementation "com.github.MrStahlfelge.gdx-websockets:core:$wsVersion"
     }     }
 } }
 </file> </file>
  
-<file xml GdxDefinition.gwt.xml> 
-  <inherits name='com.github.czyzby.websocket.GdxWebSocketGwt' /> 
-  <inherits name='com.github.czyzby.websocket.GdxWebSocket' /> 
-</file> 
- 
-Recordeu també que per tal que funcionin les comunicacions en Android cal activar els permisos adequats: 
- 
-<file xml AndroidManifest.xml> 
-    <uses-permission android:name="android.permission.INTERNET" /> 
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
-</file> 
 <-- <--
  
Línia 90: Línia 108:
   * Podem enviar des de qualsevol part del codi inclús des del ''render'' tot i que convé no abusar.   * Podem enviar des de qualsevol part del codi inclús des del ''render'' tot i que convé no abusar.
   * Per rebre dades del servidor ho fem mitjançant l'objecte ''WebSocketListener''.   * Per rebre dades del servidor ho fem mitjançant l'objecte ''WebSocketListener''.
 +
 +<WRAP important>
 +El protocol WebSockets <nowiki>(ws://)</nowiki> funciona sobre HTTP. Si estem treballant en producció sobre HTTPS, el protocol és SecureWebSockets <nowiki>(wss://)</nowiki>. El codi aquí indicat serà una mica diferent, caldrà instanciar ''WebSockets.toSecureWebSocketUrl'' enlloc de ''WebSockets.toWebSocketUrl''.
 +
 +La variable ''address'' ha de ser el nom del servidor (no val la IP !), sense prefix, port 443 i emprant la crida que s'explica a continuació.
 +
 +<code java>
 +socket = WebSockets.newSocket(WebSockets.toSecureWebSocketUrl(address, port));
 +</code>
 +
 +</WRAP>
  
 <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 103: Línia 135:
             address = "10.0.2.2";             address = "10.0.2.2";
         socket = WebSockets.newSocket(WebSockets.toWebSocketUrl(address, port));         socket = WebSockets.newSocket(WebSockets.toWebSocketUrl(address, port));
 +        // ULL: si és a traves de HTTPS , el protocol seria wss enlloc de ws
 +        //socket = WebSockets.newSocket(WebSockets.toSecureWebSocketUrl(address, port));
         socket.setSendGracefully(false);         socket.setSendGracefully(false);
         socket.addListener((WebSocketListener) new MyWSListener());         socket.addListener((WebSocketListener) new MyWSListener());
Línia 161: Línia 195:
  
 Podem emprar la [[https://www.npmjs.com/package/ws|llibreria WS per a NodeJS]]. Podem emprar la [[https://www.npmjs.com/package/ws|llibreria WS per a NodeJS]].
-   
---> 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 168: Línia 200:
   $ cd ws1   $ cd ws1
   $ npm init   $ npm init
-  $ npm install http ws+  $ npm install http ws express uuid
  
 Afegeix ''index.js'' i posa'l en marxa: Afegeix ''index.js'' i posa'l en marxa:
   $ node index.js   $ node index.js
  
-Cal indicar el projecte com a "module": + 
-<file javascript package.json> +--Exemple 1WebSockets simple#
-+
-  "name""ws1", +
-  "type": "module", +
-  ... +
-+
-</file>+
  
 <file javascript index.js> <file javascript index.js>
-import { createServer } from 'http'; +const { createServer } = require('http')
-import { WebSocketServer } from 'ws';+const { WebSocketServer } = require('ws');
  
 const server = createServer(); const server = createServer();
Línia 209: Línia 235:
 }); });
  
 +</file>
 +<--
 +
 +
 +
 +-->Exemple 2: WebSockets + HTTP#
 +
 +<file javascript index,js>
 +const express = require('express')
 +const http = require('http');
 +const WebSocket = require('ws')
 +
 +const app = express()
 +const httpServer = http.createServer(app);
 +const wss = new WebSocket.Server({ server: httpServer })
 +
 +const { v4: uuidv4 } = require('uuid')
 +const port = 8888
 +var clients = {}
 +
 +// HTTP ROUTES
 +app.use(express.static('public'))
 +app.get('/',root);
 +
 +
 +// WS client connections
 +wss.on('connection', function connection(ws) {
 +  var userid = uuidv4();
 +  console.log('Nova connexió: '+userid);
 +  clients[userid] = { "id":userid, "ws":ws, pos:{} };
 +  ws.send("Benvingut id="+userid);
 +  // TODO: crear totems i actualitzar
 +
 +  ws.on('close', function close() {
 +    delete clients[userid];
 +    // TODO: esborrar totems?
 +  })
 +
 +  ws.on('error', console.error);
 +
 +  ws.on('message', function message(data) {
 +    try {
 +      // exemple per descoficar JSON
 +      var posData = JSON.parse(data);
 +      posData.id = userid;
 +      console.log('Pos data: %s', JSON.stringify(posData));
 +      // retransmetem posició a tothom
 +      broadcast(JSON.stringify(posData));
 +    } catch (e) {
 +      console.log("ERROR descodificant pos: "+e)
 +    }
 +  });
 +
 +});
 +
 +
 +// SERVER START
 +httpServer.listen(port, appListen)
 +function appListen () {
 + console.log(`Example app listening on: http://localhost:${port}`)
 +}
 +
 +// HTTP
 +/////////////////////////////////
 +async function root(req,res) {
 +    res.send("IETI Game WebSocket Server");
 +}
 +
 +
 +// 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);
 +    //}
 +  }
 +}
 </file> </file>
 <-- <--
libgdx_comunicacions.1681828136.txt.gz · Darrera modificació: 2023/04/18 14:28 per enric_mieza_sanchez