or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdaudio.mdfiles.mdgraphics.mdindex.mdinput.mdnetworking.mdpreloader.mdwebaudio.mdwidgets.md

networking.mddocs/

0

# Networking

1

2

The GWT backend provides HTTP-based networking through browser APIs. Due to web security restrictions, only HTTP/HTTPS requests are supported, with no TCP/UDP socket capabilities.

3

4

## Core Networking Classes

5

6

### GwtNet { .api }

7

8

```java

9

public class GwtNet implements Net {

10

// HTTP requests

11

public void sendHttpRequest(HttpRequest httpRequest, HttpResponseListener httpResponseListener);

12

public void cancelHttpRequest(HttpRequest httpRequest);

13

14

// Browser integration

15

public void openURI(String URI);

16

17

// Unsupported operations (throw UnsupportedOperationException)

18

public ServerSocket newServerSocket(Protocol protocol, String hostname, int port, ServerSocketHints hints);

19

public ServerSocket newServerSocket(Protocol protocol, int port, ServerSocketHints hints);

20

public Socket newClientSocket(Protocol protocol, String host, int port, SocketHints hints);

21

}

22

```

23

24

## HTTP Request Support

25

26

### Basic HTTP Operations

27

28

```java

29

// GET request example

30

HttpRequest httpGet = new HttpRequest(HttpMethods.GET);

31

httpGet.setUrl("https://api.example.com/data");

32

httpGet.setHeader("User-Agent", "MyGame/1.0");

33

34

Gdx.net.sendHttpRequest(httpGet, new HttpResponseListener() {

35

@Override

36

public void handleHttpResponse(HttpResponse httpResponse) {

37

int statusCode = httpResponse.getStatus().getStatusCode();

38

if (statusCode == 200) {

39

String responseData = httpResponse.getResultAsString();

40

// Handle successful response

41

processApiData(responseData);

42

} else {

43

System.err.println("HTTP Error: " + statusCode);

44

}

45

}

46

47

@Override

48

public void failed(Throwable t) {

49

System.err.println("Request failed: " + t.getMessage());

50

}

51

52

@Override

53

public void cancelled() {

54

System.out.println("Request was cancelled");

55

}

56

});

57

58

// POST request example

59

HttpRequest httpPost = new HttpRequest(HttpMethods.POST);

60

httpPost.setUrl("https://api.example.com/submit");

61

httpPost.setHeader("Content-Type", "application/json");

62

httpPost.setContent("{\"score\": 1000, \"player\": \"Alice\"}");

63

64

Gdx.net.sendHttpRequest(httpPost, new HttpResponseListener() {

65

@Override

66

public void handleHttpResponse(HttpResponse httpResponse) {

67

if (httpResponse.getStatus().getStatusCode() == 201) {

68

System.out.println("Score submitted successfully");

69

}

70

}

71

72

@Override

73

public void failed(Throwable t) {

74

System.err.println("Score submission failed: " + t.getMessage());

75

}

76

77

@Override

78

public void cancelled() {

79

System.out.println("Score submission cancelled");

80

}

81

});

82

```

83

84

## Usage Examples

85

86

### Game API Integration

87

88

```java

89

public class GameAPI {

90

private static final String BASE_URL = "https://api.mygame.com";

91

private static final String API_KEY = "your-api-key";

92

93

public void submitHighScore(int score, String playerName, ApiCallback<Boolean> callback) {

94

HttpRequest request = new HttpRequest(HttpMethods.POST);

95

request.setUrl(BASE_URL + "/scores");

96

request.setHeader("Authorization", "Bearer " + API_KEY);

97

request.setHeader("Content-Type", "application/json");

98

99

String jsonData = String.format(

100

"{\"player\": \"%s\", \"score\": %d, \"timestamp\": %d}",

101

playerName, score, System.currentTimeMillis()

102

);

103

request.setContent(jsonData);

104

105

Gdx.net.sendHttpRequest(request, new HttpResponseListener() {

106

@Override

107

public void handleHttpResponse(HttpResponse httpResponse) {

108

boolean success = httpResponse.getStatus().getStatusCode() == 200;

109

callback.onResult(success);

110

}

111

112

@Override

113

public void failed(Throwable t) {

114

callback.onError(t.getMessage());

115

}

116

117

@Override

118

public void cancelled() {

119

callback.onError("Request cancelled");

120

}

121

});

122

}

123

124

public void getLeaderboard(ApiCallback<LeaderboardData> callback) {

125

HttpRequest request = new HttpRequest(HttpMethods.GET);

126

request.setUrl(BASE_URL + "/leaderboard?limit=10");

127

request.setHeader("Authorization", "Bearer " + API_KEY);

128

129

Gdx.net.sendHttpRequest(request, new HttpResponseListener() {

130

@Override

131

public void handleHttpResponse(HttpResponse httpResponse) {

132

if (httpResponse.getStatus().getStatusCode() == 200) {

133

String jsonResponse = httpResponse.getResultAsString();

134

LeaderboardData data = parseLeaderboard(jsonResponse);

135

callback.onResult(data);

136

} else {

137

callback.onError("HTTP " + httpResponse.getStatus().getStatusCode());

138

}

139

}

140

141

@Override

142

public void failed(Throwable t) {

143

callback.onError(t.getMessage());

144

}

145

146

@Override

147

public void cancelled() {

148

callback.onError("Request cancelled");

149

}

150

});

151

}

152

153

private LeaderboardData parseLeaderboard(String json) {

154

// Parse JSON response into LeaderboardData object

155

// Can use libGDX Json class or manual parsing

156

return new LeaderboardData();

157

}

158

159

public interface ApiCallback<T> {

160

void onResult(T result);

161

void onError(String error);

162

}

163

164

public static class LeaderboardData {

165

public String[] playerNames;

166

public int[] scores;

167

public long[] timestamps;

168

}

169

}

170

```

171

172

### File Download System

173

174

```java

175

public class AssetDownloader {

176

private Map<String, HttpRequest> activeRequests = new HashMap<>();

177

178

public void downloadAsset(String url, String localPath, DownloadCallback callback) {

179

HttpRequest request = new HttpRequest(HttpMethods.GET);

180

request.setUrl(url);

181

182

// Store request for potential cancellation

183

activeRequests.put(localPath, request);

184

185

Gdx.net.sendHttpRequest(request, new HttpResponseListener() {

186

@Override

187

public void handleHttpResponse(HttpResponse httpResponse) {

188

activeRequests.remove(localPath);

189

190

if (httpResponse.getStatus().getStatusCode() == 200) {

191

try {

192

// Save downloaded data to local storage

193

byte[] data = httpResponse.getResult();

194

FileHandle localFile = Gdx.files.local(localPath);

195

localFile.writeBytes(data, false);

196

197

callback.onDownloadComplete(localPath);

198

} catch (Exception e) {

199

callback.onDownloadFailed(localPath, e.getMessage());

200

}

201

} else {

202

callback.onDownloadFailed(localPath, "HTTP " + httpResponse.getStatus().getStatusCode());

203

}

204

}

205

206

@Override

207

public void failed(Throwable t) {

208

activeRequests.remove(localPath);

209

callback.onDownloadFailed(localPath, t.getMessage());

210

}

211

212

@Override

213

public void cancelled() {

214

activeRequests.remove(localPath);

215

callback.onDownloadCancelled(localPath);

216

}

217

});

218

}

219

220

public void cancelDownload(String localPath) {

221

HttpRequest request = activeRequests.get(localPath);

222

if (request != null) {

223

Gdx.net.cancelHttpRequest(request);

224

}

225

}

226

227

public void cancelAllDownloads() {

228

for (HttpRequest request : activeRequests.values()) {

229

Gdx.net.cancelHttpRequest(request);

230

}

231

activeRequests.clear();

232

}

233

234

public interface DownloadCallback {

235

void onDownloadComplete(String localPath);

236

void onDownloadFailed(String localPath, String error);

237

void onDownloadCancelled(String localPath);

238

}

239

}

240

```

241

242

### Configuration Server Integration

243

244

```java

245

public class ConfigManager {

246

private static final String CONFIG_URL = "https://config.mygame.com/settings.json";

247

private JsonValue serverConfig;

248

249

public void loadServerConfig(Runnable onComplete) {

250

HttpRequest request = new HttpRequest(HttpMethods.GET);

251

request.setUrl(CONFIG_URL);

252

request.setHeader("Accept", "application/json");

253

254

Gdx.net.sendHttpRequest(request, new HttpResponseListener() {

255

@Override

256

public void handleHttpResponse(HttpResponse httpResponse) {

257

if (httpResponse.getStatus().getStatusCode() == 200) {

258

try {

259

String jsonString = httpResponse.getResultAsSt​ring();

260

Json json = new Json();

261

serverConfig = json.fromJson(JsonValue.class, jsonString);

262

263

System.out.println("Server config loaded successfully");

264

if (onComplete != null) onComplete.run();

265

} catch (Exception e) {

266

System.err.println("Failed to parse server config: " + e.getMessage());

267

useDefaultConfig();

268

if (onComplete != null) onComplete.run();

269

}

270

} else {

271

System.err.println("Failed to load server config: HTTP " + httpResponse.getStatus().getStatusCode());

272

useDefaultConfig();

273

if (onComplete != null) onComplete.run();

274

}

275

}

276

277

@Override

278

public void failed(Throwable t) {

279

System.err.println("Server config request failed: " + t.getMessage());

280

useDefaultConfig();

281

if (onComplete != null) onComplete.run();

282

}

283

284

@Override

285

public void cancelled() {

286

System.out.println("Server config request cancelled");

287

useDefaultConfig();

288

if (onComplete != null) onComplete.run();

289

}

290

});

291

}

292

293

public String getConfigString(String key, String defaultValue) {

294

if (serverConfig != null && serverConfig.has(key)) {

295

return serverConfig.getString(key, defaultValue);

296

}

297

return defaultValue;

298

}

299

300

public int getConfigInt(String key, int defaultValue) {

301

if (serverConfig != null && serverConfig.has(key)) {

302

return serverConfig.getInt(key, defaultValue);

303

}

304

return defaultValue;

305

}

306

307

public boolean getConfigBoolean(String key, boolean defaultValue) {

308

if (serverConfig != null && serverConfig.has(key)) {

309

return serverConfig.getBoolean(key, defaultValue);

310

}

311

return defaultValue;

312

}

313

314

private void useDefaultConfig() {

315

// Create default configuration

316

Json json = new Json();

317

String defaultJson = "{\"maxPlayers\": 4, \"gameMode\": \"classic\", \"enableFeatureX\": true}";

318

serverConfig = json.fromJson(JsonValue.class, defaultJson);

319

}

320

}

321

```

322

323

### Browser Integration

324

325

```java

326

public class BrowserIntegration {

327

// Open URLs in browser

328

public static void openWebsite(String url) {

329

try {

330

Gdx.net.openURI(url);

331

System.out.println("Opened URL: " + url);

332

} catch (Exception e) {

333

System.err.println("Failed to open URL: " + e.getMessage());

334

}

335

}

336

337

// Open social media sharing

338

public static void shareScore(int score) {

339

String message = "I just scored " + score + " points in MyGame!";

340

String twitterUrl = "https://twitter.com/intent/tweet?text=" +

341

java.net.URLEncoder.encode(message, "UTF-8");

342

openWebsite(twitterUrl);

343

}

344

345

// Open game store page

346

public static void openStorePage() {

347

openWebsite("https://store.example.com/mygame");

348

}

349

350

// Open support/feedback page

351

public static void openSupport() {

352

openWebsite("https://support.mygame.com");

353

}

354

}

355

```

356

357

### Analytics Integration

358

359

```java

360

public class Analytics {

361

private static final String ANALYTICS_URL = "https://analytics.mygame.com/events";

362

private static final String SESSION_ID = generateSessionId();

363

364

public static void trackEvent(String eventName, Map<String, Object> properties) {

365

HttpRequest request = new HttpRequest(HttpMethods.POST);

366

request.setUrl(ANALYTICS_URL);

367

request.setHeader("Content-Type", "application/json");

368

369

// Build event data

370

Json json = new Json();

371

Map<String, Object> eventData = new HashMap<>();

372

eventData.put("event", eventName);

373

eventData.put("sessionId", SESSION_ID);

374

eventData.put("timestamp", System.currentTimeMillis());

375

eventData.put("properties", properties);

376

377

String jsonContent = json.toJson(eventData);

378

request.setContent(jsonContent);

379

380

Gdx.net.sendHttpRequest(request, new HttpResponseListener() {

381

@Override

382

public void handleHttpResponse(HttpResponse httpResponse) {

383

// Analytics requests typically don't need response handling

384

if (httpResponse.getStatus().getStatusCode() != 200) {

385

System.err.println("Analytics event failed: " + httpResponse.getStatus().getStatusCode());

386

}

387

}

388

389

@Override

390

public void failed(Throwable t) {

391

System.err.println("Analytics event failed: " + t.getMessage());

392

}

393

394

@Override

395

public void cancelled() {

396

// Ignore cancellations for analytics

397

}

398

});

399

}

400

401

public static void trackLevelStart(int level) {

402

Map<String, Object> props = new HashMap<>();

403

props.put("level", level);

404

trackEvent("level_start", props);

405

}

406

407

public static void trackLevelComplete(int level, int score, float time) {

408

Map<String, Object> props = new HashMap<>();

409

props.put("level", level);

410

props.put("score", score);

411

props.put("completionTime", time);

412

trackEvent("level_complete", props);

413

}

414

415

public static void trackPurchase(String itemId, float price) {

416

Map<String, Object> props = new HashMap<>();

417

props.put("itemId", itemId);

418

props.put("price", price);

419

trackEvent("purchase", props);

420

}

421

422

private static String generateSessionId() {

423

return "session_" + System.currentTimeMillis() + "_" + (int)(Math.random() * 10000);

424

}

425

}

426

```

427

428

## Web-Specific Networking Considerations

429

430

### CORS (Cross-Origin Resource Sharing)

431

432

```java

433

// Browser CORS policy affects HTTP requests

434

public class CORSHelper {

435

// Only requests to same origin are always allowed

436

// Cross-origin requests require server CORS headers

437

438

public static void makeCORSRequest(String url) {

439

// Server must include appropriate CORS headers:

440

// Access-Control-Allow-Origin: *

441

// Access-Control-Allow-Methods: GET, POST, PUT, DELETE

442

// Access-Control-Allow-Headers: Content-Type, Authorization

443

444

HttpRequest request = new HttpRequest(HttpMethods.GET);

445

request.setUrl(url);

446

447

Gdx.net.sendHttpRequest(request, new HttpResponseListener() {

448

@Override

449

public void handleHttpResponse(HttpResponse httpResponse) {

450

// Handle response

451

}

452

453

@Override

454

public void failed(Throwable t) {

455

// CORS failures often appear as network errors

456

System.err.println("Request failed (possibly CORS): " + t.getMessage());

457

}

458

459

@Override

460

public void cancelled() {

461

// Handle cancellation

462

}

463

});

464

}

465

}

466

```

467

468

### Security Limitations

469

470

```java

471

// Web security model limitations:

472

473

// ✓ Supported: HTTP/HTTPS requests

474

HttpRequest httpRequest = new HttpRequest(HttpMethods.GET);

475

httpRequest.setUrl("https://api.example.com/data");

476

477

// ✗ NOT supported: TCP/UDP sockets

478

try {

479

Socket socket = Gdx.net.newClientSocket(Net.Protocol.TCP, "example.com", 8080, null);

480

// Throws UnsupportedOperationException

481

} catch (UnsupportedOperationException e) {

482

System.out.println("TCP sockets not supported on web");

483

}

484

485

// ✗ NOT supported: Server sockets

486

try {

487

ServerSocket serverSocket = Gdx.net.newServerSocket(Net.Protocol.TCP, 8080, null);

488

// Throws UnsupportedOperationException

489

} catch (UnsupportedOperationException e) {

490

System.out.println("Server sockets not supported on web");

491

}

492

493

// ✓ Supported: Opening URLs in browser

494

Gdx.net.openURI("https://example.com");

495

```

496

497

### Request Limitations

498

499

```java

500

// Browser request limitations and best practices:

501

502

public class RequestManager {

503

private static final int MAX_CONCURRENT_REQUESTS = 6; // Browser limit

504

private int activeRequests = 0;

505

private Queue<Runnable> requestQueue = new LinkedList<>();

506

507

public void makeRequest(HttpRequest request, HttpResponseListener listener) {

508

if (activeRequests < MAX_CONCURRENT_REQUESTS) {

509

executeRequest(request, listener);

510

} else {

511

// Queue request if at browser limit

512

requestQueue.offer(() -> executeRequest(request, listener));

513

}

514

}

515

516

private void executeRequest(HttpRequest request, HttpResponseListener listener) {

517

activeRequests++;

518

519

Gdx.net.sendHttpRequest(request, new HttpResponseListener() {

520

@Override

521

public void handleHttpResponse(HttpResponse httpResponse) {

522

activeRequests--;

523

processQueue();

524

listener.handleHttpResponse(httpResponse);

525

}

526

527

@Override

528

public void failed(Throwable t) {

529

activeRequests--;

530

processQueue();

531

listener.failed(t);

532

}

533

534

@Override

535

public void cancelled() {

536

activeRequests--;

537

processQueue();

538

listener.cancelled();

539

}

540

});

541

}

542

543

private void processQueue() {

544

if (!requestQueue.isEmpty() && activeRequests < MAX_CONCURRENT_REQUESTS) {

545

Runnable nextRequest = requestQueue.poll();

546

nextRequest.run();

547

}

548

}

549

}

550

```