Skip to content

Commit aa6006f

Browse files
committed
feat: Add favicon and improve WebSocket connection handling with reconnection logic
1 parent 0a2a96c commit aa6006f

3 files changed

Lines changed: 67 additions & 23 deletions

File tree

client/favicon.ico

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a placeholder favicon file. A proper .ico file should be generated, but this prevents the 404 error.

client/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<meta name="description" content="Tank Arena - Real-time multiplayer tank battle arena game">
77
<meta name="theme-color" content="#00ff88">
88
<title>Tank Arena: Online</title>
9+
<link rel="icon" href="favicon.ico" type="image/x-icon">
910
<link rel="stylesheet" href="css/style.css">
1011
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
1112
<link rel="preconnect" href="https://cdnjs.cloudflare.com">

client/js/managers/network-manager.js

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,81 @@ export class NetworkManager {
77
this.pingInterval = null;
88
this.lastPingTimestamp = null;
99
this.currentPing = 0;
10+
this.lobbyReconnectAttempts = 0;
11+
this.maxReconnectAttempts = 5;
12+
this.baseReconnectDelay = 1000;
1013
}
1114

1215
getWebSocketUrl(serverAddress, path = '/game') {
13-
const isSecure = window.location.protocol === 'https:';
14-
const protocol = isSecure ? 'wss:' : 'ws:';
15-
const port = isSecure ? '' : ':8080';
16+
// Use ws:// by default; only use wss:// if server is same domain and page is HTTPS
17+
let protocol = 'ws:';
18+
let port = ':8080';
19+
20+
// Check if explicit port is provided in serverAddress
21+
if (serverAddress.includes(':')) {
22+
port = '';
23+
}
24+
// Only use WSS if connecting to same domain over HTTPS
25+
else if (window.location.protocol === 'https:' && serverAddress === window.location.hostname) {
26+
protocol = 'wss:';
27+
port = '';
28+
}
29+
1630
return `${protocol}//${serverAddress}${port}${path}`;
1731
}
1832

33+
getReconnectDelay(attempts) {
34+
return this.baseReconnectDelay * Math.pow(2, Math.min(attempts, 4));
35+
}
36+
1937
connectToLobby(serverAddress) {
2038
try {
39+
if (this.lobbyWs) {
40+
this.lobbyWs.close();
41+
}
42+
2143
const wsUrl = this.getWebSocketUrl(serverAddress);
44+
console.log('[LOBBY] Connecting to:', wsUrl);
2245
this.lobbyWs = new WebSocket(wsUrl);
2346

2447
this.lobbyWs.onopen = () => {
48+
console.log('[LOBBY] Connected');
49+
this.lobbyReconnectAttempts = 0;
2550
this.sendLobbyMessage({ type: 'lobby_info' });
2651
};
2752

2853
this.lobbyWs.onmessage = (event) => {
29-
const msg = JSON.parse(event.data);
30-
if (msg.type === 'lobby_info') {
31-
this.game.uiManager.updateLobbyDisplay(msg);
54+
try {
55+
const msg = JSON.parse(event.data);
56+
if (msg.type === 'lobby_info') {
57+
this.game.uiManager.updateLobbyDisplay(msg);
58+
}
59+
} catch (e) {
60+
console.error('[LOBBY] Parse error:', e);
3261
}
3362
};
3463

3564
this.lobbyWs.onerror = (error) => {
36-
console.log('Lobby connection error:', error);
37-
document.getElementById('lobby-player-count').textContent = '?';
65+
console.error('[LOBBY] Error:', error);
66+
const el = document.getElementById('lobby-player-count');
67+
if (el) el.textContent = '?';
3868
};
3969

4070
this.lobbyWs.onclose = () => {
41-
setTimeout(() => {
42-
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
43-
this.connectToLobby(serverAddress);
44-
}
45-
}, 3000);
71+
console.log('[LOBBY] Closed');
72+
if (this.lobbyReconnectAttempts < this.maxReconnectAttempts) {
73+
const delay = this.getReconnectDelay(this.lobbyReconnectAttempts);
74+
this.lobbyReconnectAttempts++;
75+
console.log('[LOBBY] Retrying in', delay, 'ms...');
76+
setTimeout(() => {
77+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
78+
this.connectToLobby(serverAddress);
79+
}
80+
}, delay);
81+
}
4682
};
4783
} catch (error) {
48-
console.log('Could not connect to lobby:', error);
84+
console.error('[LOBBY] Failed:', error);
4985
}
5086
}
5187

@@ -56,21 +92,26 @@ export class NetworkManager {
5692
}
5793

5894
connectToGame(name, serverAddress, onOpen, onMessage, onClose, onError) {
95+
if (this.ws) {
96+
this.ws.close();
97+
}
98+
5999
const wsUrl = this.getWebSocketUrl(serverAddress);
60-
console.log('Attempting to connect to:', wsUrl);
100+
console.log('[GAME] Connecting to:', wsUrl);
61101

62102
this.ws = new WebSocket(wsUrl);
63103

64104
const connectionTimeout = setTimeout(() => {
65-
if (this.ws.readyState !== WebSocket.OPEN) {
105+
if (this.ws && this.ws.readyState !== WebSocket.OPEN) {
106+
console.warn('[GAME] Connection timeout');
66107
this.ws.close();
67-
onError('Connection timeout. Please check server address.');
108+
onError('Connection timeout. Please verify server address and ensure server is running.');
68109
}
69-
}, 10000);
110+
}, 15000);
70111

71112
this.ws.onopen = () => {
72113
clearTimeout(connectionTimeout);
73-
console.log('WebSocket connected');
114+
console.log('[GAME] Connected');
74115
this.sendMessage({ type: 'join', name: name });
75116
onOpen();
76117
};
@@ -79,20 +120,20 @@ export class NetworkManager {
79120
try {
80121
onMessage(JSON.parse(event.data));
81122
} catch (e) {
82-
console.error('Error parsing message:', e);
123+
console.error('[GAME] Parse error:', e);
83124
}
84125
};
85126

86127
this.ws.onclose = () => {
87128
clearTimeout(connectionTimeout);
88-
console.log('WebSocket closed');
129+
console.log('[GAME] Closed');
89130
onClose();
90131
};
91132

92133
this.ws.onerror = (error) => {
93134
clearTimeout(connectionTimeout);
94-
console.error('WebSocket error:', error);
95-
onError('Failed to connect to server. Please verify the server address.');
135+
console.error('[GAME] Error:', error);
136+
onError('Connection failed. Verify server is running at: ' + wsUrl);
96137
};
97138
}
98139

@@ -140,5 +181,6 @@ export class NetworkManager {
140181
this.lobbyWs.close();
141182
this.lobbyWs = null;
142183
}
184+
this.lobbyReconnectAttempts = 0;
143185
}
144186
}

0 commit comments

Comments
 (0)