Skip to content

Commit c93bcc5

Browse files
committed
feat: implement shared port configuration and dynamic port selection for WebSocket server
1 parent b5ca527 commit c93bcc5

File tree

6 files changed

+153
-122
lines changed

6 files changed

+153
-122
lines changed

.github/workflows/python-package.yml

Lines changed: 37 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -121,111 +121,53 @@ jobs:
121121
prerelease: ${{ steps.get_version.outputs.IS_PRERELEASE }}
122122

123123
body: |
124-
# 🚀 KickViewerBOT Beta V3 - Major Architecture Upgrade
125-
126-
## 🏗️ Revolutionary Architecture Redesign
127-
128-
**Beta V3 introduces a complete architectural overhaul** that separates the frontend and backend into distinct services, bringing enterprise-grade reliability and developer flexibility to KickViewerBOT!
129-
130-
### ⚡ New Client-Server Architecture
131-
132-
**What Changed:**
133-
- **Frontend:** Now runs as a standalone web server (Next.js)
134-
- **Backend:** Operates as a local service on your PC
135-
- **Communication:** Real-time WebSocket connection between frontend and backend
136-
- **Result:** Modern, scalable, and incredibly responsive architecture
137-
138-
### 🎯 Why This Matters for You
139-
140-
**Enhanced Reliability:**
141-
- 🔒 **More Stable Connections:** WebSocket-based communication ensures consistent real-time updates
142-
- 🔄 **Auto-Reconnection:** Frontend automatically reconnects if connection drops
143-
- 📊 **Better Error Handling:** Isolated services mean one component failure doesn't crash the entire app
144-
- ⚡ **Faster Response Times:** Dedicated server processes improve overall performance
145-
146-
**Superior Developer Experience:**
147-
- 🛠️ **Independent Updates:** Frontend and backend can be updated separately
148-
- 🧪 **Easier Testing:** Each component can be tested in isolation
149-
- 🚀 **Faster Development:** Hot reload and modern dev tools for quicker iterations
150-
- 🎨 **Better UI Framework:** Next.js provides cutting-edge web capabilities
151-
152-
**Future-Proof Foundation:**
153-
- 📱 **Multi-Platform Ready:** Architecture supports future mobile apps or web dashboard
154-
- 🌐 **Remote Access Potential:** Foundation for future remote monitoring features
155-
- 🔌 **Plugin System Ready:** Modular design enables future extensibility
156-
- 📈 **Scalability:** Can handle more viewers and features without performance degradation
157-
158-
### 🔧 Technical Highlights
159-
160-
**Backend Service:**
161-
- Python-based local service handling all bot operations
162-
- WebSocket server on port 8080 for real-time communication
163-
- Improved proxy management and connection stability
164-
- Enhanced logging and debugging capabilities
165-
166-
**Frontend Application:**
167-
- Next.js 15 with React 18 for modern UI
168-
- Real-time WebSocket client for instant updates
169-
- Beautiful glassmorphism design with smooth animations
170-
- Dark/Light theme support with automatic detection
171-
- Responsive design for all screen sizes
172-
173-
**Communication Layer:**
174-
- Bidirectional WebSocket protocol
175-
- JSON-based message format for clarity
176-
- Automatic reconnection with exponential backoff
177-
- Health monitoring and status indicators
178-
179-
### 🎨 User Experience Improvements
180-
181-
**Visual Enhancements:**
182-
- ✨ Smooth page transitions and animations
183-
- 🎯 Real-time stats updates with no lag
184-
- 📊 Better data visualization
185-
- 🔔 Smart update notifications (non-intrusive toasts)
186-
- 🌈 Adaptive theming for better readability
187-
188-
**Monitoring Features:**
189-
- 📈 Live viewer count tracking
190-
- 🔄 Connection status indicators
191-
- ⚙️ Advanced settings panel
192-
- 📊 Performance metrics dashboard
193-
- 🎮 Streamlined bot controls
194-
195-
### 🐛 Bug Fixes & Improvements
196-
197-
- ✅ Fixed connection stability issues
198-
- ✅ Improved error recovery mechanisms
199-
- ✅ Enhanced proxy rotation logic
200-
- ✅ Better memory management
201-
- ✅ Resolved UI state synchronization issues
202-
- ✅ Fixed update checker notification persistence
203-
204-
### ⚠️ Breaking Changes
205-
206-
**Important Notes:**
207-
- This is a **beta release** - please report any issues on GitHub
208-
- The new architecture requires both frontend and backend to run together
124+
# 🚀 KickViewerBOT – Smarter, Simpler, More Reliable!
125+
126+
## ✨ What’s New in This Release?
127+
128+
### 🔥 Next-Level Connectivity & User Experience
129+
130+
- **Automatic Port Discovery:** No more port conflicts! The backend now scans and selects an available port for you. The frontend instantly detects and connects—no manual setup, no headaches.
131+
- **Seamless Frontend-Backend Sync:** Both parts of the app share a single, smart configuration. You can move, restart, or run multiple instances—KickViewerBOT adapts instantly.
132+
- **Crystal-Clear Error Messages:** If a port is busy, you get a friendly message and a clear solution. No more cryptic errors!
133+
- **Zero Config, Zero Stress:** All connection URLs and ports are generated and synchronized automatically. Just launch and go!
134+
- **Rock-Solid Reliability:** Even if your environment changes, KickViewerBOT keeps running and reconnects without user intervention.
135+
136+
### 🔧 Under the Hood
137+
138+
- **Unified Port Management:** Both backend and frontend use a shared config for all connection logic. No more mismatches or manual edits.
139+
- **Smarter Startup:** The backend tries a list of recommended ports and picks the first available. The frontend scans the same list, so you always connect on the first try.
140+
- **Enhanced Logging:** Startup and error logs are now clear, actionable, and user-friendly.
141+
142+
### 🔍 Why You’ll Love This Update
143+
144+
- **Plug & Play:** Download, run, and you’re online—no technical skills required.
145+
- **No More “Port Already in Use” Errors:** The app handles everything for you, even if you have other services running.
146+
- **Future-Proof:** This foundation makes future updates, remote access, and multi-instance support a breeze.
209147
210148
---
211149
212-
## 📥 Download & Installation
150+
## 🐛 Bug Fixes & Improvements
213151
214-
**This is the biggest update to KickViewerBOT ever!**
152+
- Improved connection stability and error handling
153+
- Automatic frontend-backend sync for all connection settings
154+
- Clearer logs and user feedback on startup
155+
- Unified configuration for easier maintenance
156+
157+
---
215158
216-
The new architecture provides a solid foundation for years of future improvements while delivering better performance and reliability today.
159+
## 📥 How to Get Started
217160
218-
### Getting Started:
219-
1. Download the appropriate version for your OS
220-
2. Run the application (both services start automatically)
221-
3. Access the interface (opens automatically in your browser)
222-
4. Enjoy the enhanced experience!
161+
1. Download the version for your OS
162+
2. Run the app (both services start automatically)
163+
3. The interface opens in your browser—no setup required!
164+
4. Enjoy a smoother, smarter KickViewerBOT experience 🚀
223165
224-
**Need Help?** Check out our [GitHub Issues](https://github.com/H1B0B0/Kick-Viewerbot/issues) or join our community!
166+
**Need help?** [Open an issue](https://github.com/H1B0B0/Kick-Viewerbot/issues) or join our community!
225167
226168
---
227169
228-
*Thank you for being part of the KickViewerBOT Beta program! Your feedback helps make this tool better for everyone.* 🙏
170+
*Thank you for supporting KickViewerBOT! Your feedback drives every improvement.* 🙏
229171
230172
draft: false
231173

backend/main.py

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -382,23 +382,68 @@ def index():
382382
# Main
383383
# ============================================
384384

385+
def find_available_port(preferred_ports, host='0.0.0.0'):
386+
"""Trouve un port disponible parmi la liste fournie"""
387+
import socket
388+
389+
for port in preferred_ports:
390+
try:
391+
# Tester si le port est disponible
392+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
393+
sock.settimeout(1)
394+
result = sock.connect_ex((host if host != '0.0.0.0' else 'localhost', port))
395+
sock.close()
396+
397+
if result != 0: # Port disponible
398+
return port
399+
except Exception as e:
400+
logger.debug(f"Error testing port {port}: {e}")
401+
continue
402+
403+
# Si aucun port de la liste n'est disponible, laisser le système en choisir un
404+
return None
405+
385406
if __name__ == '__main__':
386407
import argparse
387408
import webbrowser
388409
from threading import Timer
389410

411+
# Import shared port configuration
412+
sys.path.insert(0, str(Path(__file__).parent.parent))
413+
try:
414+
from shared_config import AVAILABLE_PORTS, DEFAULT_HOST
415+
except ImportError:
416+
logger.warning("Could not import shared_config, using defaults")
417+
AVAILABLE_PORTS = [8765, 9876, 7890, 6543, 5432, 8081, 8082, 8083]
418+
DEFAULT_HOST = '0.0.0.0'
419+
390420
parser = argparse.ArgumentParser()
391-
parser.add_argument('--port', type=int, default=8080, help='Port to run on')
392-
parser.add_argument('--host', default='0.0.0.0', help='Host to bind to')
421+
parser.add_argument('--port', type=int, default=None, help='Port to run on (if not specified, will try from the available list)')
422+
parser.add_argument('--host', default=DEFAULT_HOST, help='Host to bind to')
393423
parser.add_argument('--no-browser', action='store_true', help='Do not open browser')
394424
args = parser.parse_args()
395425

426+
# Trouver un port disponible
427+
if args.port:
428+
selected_port = args.port
429+
logger.info(f"Using specified port: {selected_port}")
430+
else:
431+
selected_port = find_available_port(AVAILABLE_PORTS, args.host)
432+
if selected_port is None:
433+
logger.error("Could not find any available port from the configured list!")
434+
print("❌ Aucun port disponible trouvé. Veuillez fermer certaines applications et réessayer.")
435+
sys.exit(1)
436+
logger.info(f"Found available port: {selected_port}")
437+
396438
print("=" * 60)
397439
print("🚀 Kick Viewer Bot - WebSocket Server")
398440
print("=" * 60)
399-
print(f"📡 WebSocket: ws://{args.host}:{args.port}/socket.io/")
400-
print(f"🌐 HTTP: http://{args.host}:{args.port}")
401-
print(f"✅ Health: http://{args.host}:{args.port}/health")
441+
print(f"📡 WebSocket: ws://{args.host}:{selected_port}/socket.io/")
442+
print(f"🌐 HTTP: http://{args.host}:{selected_port}")
443+
print(f"✅ Health: http://{args.host}:{selected_port}/health")
444+
print("=" * 60)
445+
print(f"\n🔌 Port utilisé: {selected_port}")
446+
print(f"💡 Le frontend essaiera automatiquement de se connecter à ce port")
402447
print("=" * 60)
403448

404449
# Open browser after 1.5 seconds if not disabled
@@ -408,10 +453,17 @@ def index():
408453

409454
print("\nPress Ctrl+C to stop\n")
410455

411-
socketio.run(
412-
app,
413-
host=args.host,
414-
port=args.port,
415-
debug=False,
416-
use_reloader=False
417-
)
456+
try:
457+
socketio.run(
458+
app,
459+
host=args.host,
460+
port=selected_port,
461+
debug=False,
462+
use_reloader=False
463+
)
464+
except OSError as e:
465+
if "Address already in use" in str(e):
466+
logger.error(f"Port {selected_port} is already in use!")
467+
print(f"❌ Le port {selected_port} est déjà utilisé. Réessayez ou spécifiez un autre port avec --port")
468+
else:
469+
raise

frontend/config/ports.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Shared port configuration
3+
* Must match the backend shared_config.py
4+
*/
5+
6+
// Ports peu utilisés par défaut, dans l'ordre de préférence
7+
export const AVAILABLE_PORTS = [
8+
8765, // Port peu commun
9+
9876, // Rarement utilisé
10+
7890, // Peu utilisé
11+
6543, // Rarement occupé
12+
5432, // Peut être occupé par PostgreSQL
13+
8081, // Alternative à 8080
14+
8082, // Alternative à 8080
15+
8083, // Alternative à 8080
16+
];
17+
18+
// Générer toutes les URLs possibles (localhost + 127.0.0.1)
19+
export const generateConnectionUrls = (): string[] => {
20+
const urls: string[] = [];
21+
22+
for (const port of AVAILABLE_PORTS) {
23+
urls.push(`http://localhost:${port}`);
24+
urls.push(`http://127.0.0.1:${port}`);
25+
}
26+
27+
return urls;
28+
};

frontend/services/LocalServiceConnector.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
import { io, Socket } from "socket.io-client";
7+
import { generateConnectionUrls } from "../config/ports";
78

89
export type ConnectionStatus =
910
| "disconnected"
@@ -24,14 +25,8 @@ class LocalServiceConnector {
2425
private reconnectAttempts = 0;
2526
private maxReconnectAttempts = 5;
2627

27-
// Try multiple possible local addresses
28-
private possibleUrls = [
29-
"http://localhost:3001",
30-
"http://localhost:443",
31-
"https://localhost:443",
32-
"http://127.0.0.1:3001",
33-
"http://127.0.0.1:443",
34-
];
28+
// Try multiple possible local addresses (from shared config)
29+
private possibleUrls = generateConnectionUrls();
3530

3631
private currentUrlIndex = 0;
3732

frontend/services/WebSocketService.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* WebSocket Service - Communication complète via WebSocket
33
*/
44
import { io, Socket } from "socket.io-client";
5+
import { generateConnectionUrls } from "../config/ports";
56

67
export type ConnectionStatus =
78
| "disconnected"
@@ -51,13 +52,8 @@ class WebSocketService {
5152
private status: ConnectionStatus = "disconnected";
5253
private callbacks: Callbacks = {};
5354

54-
// URLs possibles pour le service local
55-
private urls = [
56-
"http://localhost:8080",
57-
"http://localhost:3001",
58-
"http://127.0.0.1:8080",
59-
"http://127.0.0.1:3001",
60-
];
55+
// URLs possibles pour le service local (générées depuis la config partagée)
56+
private urls = generateConnectionUrls();
6157

6258
private currentUrl = "";
6359

shared_config.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""
2+
Shared configuration between backend and frontend
3+
Liste de ports à essayer pour le serveur WebSocket
4+
"""
5+
6+
# Ports peu utilisés par défaut, dans l'ordre de préférence
7+
AVAILABLE_PORTS = [
8+
8765, # Port peu commun
9+
9876, # Rarement utilisé
10+
7890, # Peu utilisé
11+
6543, # Rarement occupé
12+
5432, # Peut être occupé par PostgreSQL
13+
8081, # Alternative à 8080
14+
8082, # Alternative à 8080
15+
8083, # Alternative à 8080
16+
]
17+
18+
DEFAULT_HOST = '0.0.0.0'

0 commit comments

Comments
 (0)