A Node.js WebSocket relay service that solves the "one connection per IP" limitation of the Backpack.tf WebSocket API. This service maintains a single connection to Backpack.tf and relays messages to multiple local clients.
Backpack.tf's WebSocket API only allows one connection per IP address. This relay service:
- Maintains a single connection to
wss://ws.backpack.tf/events - Allows multiple local services to connect to the relay
- Broadcasts all Backpack.tf messages to connected local clients
- Provides health monitoring and connection management
npm installCreate a .env file (optional):
PORT=3001
BACKPACK_WS_URL=wss://ws.backpack.tf/events
LOG_LEVEL=INFO# Development mode with auto-restart
npm run dev
# Production mode
npm start| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Service information and available endpoints |
/health |
GET | Simple health check (200/503) |
/status |
GET | Detailed service status and statistics |
/api/clients |
GET | Connected clients information |
ws://localhost:3001/relay |
WebSocket | Client connection endpoint |
const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost:3001/relay');
ws.on('open', () => {
console.log('Connected to Backpack.tf relay');
});
ws.on('message', (data) => {
const message = JSON.parse(data);
// Handle different message types
switch (message.type) {
case 'relay_status':
console.log('Relay status:', message);
break;
case 'backpack_connected':
console.log('Backpack.tf connected');
break;
case 'backpack_disconnected':
console.log('Backpack.tf disconnected');
break;
default:
// Regular Backpack.tf messages
console.log('Backpack.tf message:', message);
}
});The relay sends several types of messages:
relay_status- Initial connection statusbackpack_connected- Backpack.tf connection establishedbackpack_disconnected- Backpack.tf connection lostbackpack_error- Backpack.tf connection error
All original Backpack.tf WebSocket messages are relayed unchanged.
// Send ping to maintain connection
ws.send(JSON.stringify({ type: 'ping' }));
// Server responds with pong
ws.on('message', (data) => {
const message = JSON.parse(data);
if (message.type === 'pong') {
console.log('Heartbeat acknowledged');
}
});| Variable | Default | Description |
|---|---|---|
PORT |
3001 |
HTTP server port |
BACKPACK_WS_URL |
wss://ws.backpack.tf/events |
Backpack.tf WebSocket URL |
LOG_LEVEL |
INFO |
Logging level (ERROR, WARN, INFO, DEBUG) |
- Automatic Reconnection: Reconnects to Backpack.tf with exponential backoff
- Client Management: Tracks connected clients with heartbeat monitoring
- Health Monitoring: HTTP endpoints for service health and status
- Graceful Shutdown: Properly closes all connections on shutdown
- Comprehensive Logging: Structured logging with configurable levels
curl http://localhost:3001/healthResponse:
{
"healthy": true,
"backpackConnected": true,
"connectedClients": 3,
"uptime": 123456,
"messagesRelayed": 4567
}curl http://localhost:3001/statuscurl http://localhost:3001/api/clientsBefore (direct connection):
const ws = new WebSocket('wss://ws.backpack.tf/events');After (via relay):
const ws = new WebSocket('ws://localhost:3001/relay');You can now run multiple services that need Backpack.tf data:
- TF2 Spell Handler
- Price monitoring service
- Trading bot
- Analytics service
All connecting to the same relay without IP conflicts.
npm run devnpm startFROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY src/ ./src/
EXPOSE 3001
CMD ["npm", "start"]The service provides structured logging with timestamps:
[2025-09-18T10:30:00.000Z] [INFO] π Backpack.tf WebSocket Relay Server running on port 3001
[2025-09-18T10:30:01.000Z] [INFO] β
Connected to Backpack.tf WebSocket
[2025-09-18T10:30:05.000Z] [INFO] π± Client 1 connected from ::1
[2025-09-18T10:30:10.000Z] [DEBUG] π¨ Relayed message type: listing to 1 clients
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
MIT License - see LICENSE file for details.
Connection Refused
- Ensure the relay service is running on the correct port
- Check firewall settings
No Messages Received
- Verify Backpack.tf WebSocket connection status via
/statusendpoint - Check if the service has proper internet connectivity
Client Disconnections
- The relay implements heartbeat monitoring (30s intervals)
- Ensure clients respond to ping messages
For issues and questions:
- Check the logs for error messages
- Verify service status via
/healthendpoint - Review the detailed status at
/status - Check network connectivity to Backpack.tf