WebSocket Connection Guide
Complete guide to establishing and maintaining WebSocket connections for real-time data streaming from Vibe Trading.
Overview
WebSocket connections provide real-time, bidirectional communication with the Vibe Trading platform. This allows you to receive live market data, order updates, and AI signals without polling the REST API.
Connection Details
WebSocket URL
wss://ws.vibetrading.tech/ws
Connection Parameters
- Protocol: WebSocket (WSS for secure connections)
- Authentication: API key and signature required
- Heartbeat: 30-second ping/pong to maintain connection
- Reconnection: Automatic reconnection with exponential backoff
Authentication
Connection Authentication
WebSocket connections require authentication using your API credentials.
Authentication Message:
{
"type": "auth",
"apiKey": "your_api_key",
"timestamp": 1640995200,
"signature": "calculated_signature"
}
Signature Generation
Same HMAC-SHA256 signature generation as REST API:
function generateWebSocketSignature(secretKey, apiKey, timestamp) {
const message = apiKey + timestamp;
return crypto.createHmac("sha256", secretKey).update(message).digest("hex");
}
Authentication Response
{
"type": "auth_success",
"message": "Authentication successful",
"timestamp": 1640995200
}
Connection Management
Establishing Connection
JavaScript/Node.js
const WebSocket = require("ws");
const crypto = require("crypto");
class VibeTradingWebSocket {
constructor(apiKey, secretKey) {
this.apiKey = apiKey;
this.secretKey = secretKey;
this.ws = null;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectInterval = 1000;
}
connect() {
this.ws = new WebSocket("wss://ws.vibetrading.tech/ws");
this.ws.on("open", () => {
console.log("WebSocket connected");
this.authenticate();
this.reconnectAttempts = 0;
});
this.ws.on("message", (data) => {
this.handleMessage(JSON.parse(data));
});
this.ws.on("close", (code, reason) => {
console.log(`WebSocket closed: ${code} ${reason}`);
this.handleReconnect();
});
this.ws.on("error", (error) => {
console.error("WebSocket error:", error);
});
}
authenticate() {
const timestamp = Math.floor(Date.now() / 1000);
const signature = this.generateSignature(timestamp);
const authMessage = {
type: "auth",
apiKey: this.apiKey,
timestamp: timestamp,
signature: signature,
};
this.ws.send(JSON.stringify(authMessage));
}
generateSignature(timestamp) {
const message = this.apiKey + timestamp;
return crypto
.createHmac("sha256", this.secretKey)
.update(message)
.digest("hex");
}
handleMessage(message) {
switch (message.type) {
case "auth_success":
console.log("Authentication successful");
this.subscribeToChannels();
break;
case "auth_error":
console.error("Authentication failed:", message.error);
break;
case "pong":
// Heartbeat response
break;
default:
this.processDataMessage(message);
}
}
subscribeToChannels() {
// Subscribe to desired channels
const subscriptions = [
{ type: "subscribe", channel: "ticker", symbol: "BTC/USD" },
{ type: "subscribe", channel: "orderbook", symbol: "BTC/USD" },
{ type: "subscribe", channel: "trades", symbol: "BTC/USD" },
];
subscriptions.forEach((sub) => {
this.ws.send(JSON.stringify(sub));
});
}
handleReconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
const delay =
this.reconnectInterval * Math.pow(2, this.reconnectAttempts - 1);
console.log(
`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`
);
setTimeout(() => {
this.connect();
}, delay);
} else {
console.error("Max reconnection attempts reached");
}
}
processDataMessage(message) {
// Process incoming data messages
console.log("Received data:", message);
}
sendPing() {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({ type: "ping" }));
}
}
close() {
if (this.ws) {
this.ws.close();
}
}
}
// Usage
const ws = new VibeTradingWebSocket("your_api_key", "your_secret_key");
ws.connect();
// Set up heartbeat
setInterval(() => {
ws.sendPing();
}, 30000);
Python
import asyncio
import websockets
import json
import hmac
import hashlib
import time
class VibeTradingWebSocket:
def __init__(self, api_key, secret_key):
self.api_key = api_key
self.secret_key = secret_key
self.websocket = None
self.reconnect_attempts = 0
self.max_reconnect_attempts = 5
self.reconnect_interval = 1
async def connect(self):
uri = "wss://ws.vibetrading.tech/ws"
try:
self.websocket = await websockets.connect(uri)
print("WebSocket connected")
await self.authenticate()
self.reconnect_attempts = 0
# Start listening for messages
await self.listen()
except websockets.exceptions.ConnectionClosed:
print("WebSocket connection closed")
await self.handle_reconnect()
except Exception as e:
print(f"WebSocket error: {e}")
await self.handle_reconnect()
async def authenticate(self):
timestamp = int(time.time())
signature = self.generate_signature(timestamp)
auth_message = {
"type": "auth",
"apiKey": self.api_key,
"timestamp": timestamp,
"signature": signature
}
await self.websocket.send(json.dumps(auth_message))
def generate_signature(self, timestamp):
message = self.api_key + str(timestamp)
return hmac.new(
self.secret_key.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
async def listen(self):
async for message in self.websocket:
data = json.loads(message)
await self.handle_message(data)
async def handle_message(self, message):
message_type = message.get("type")
if message_type == "auth_success":
print("Authentication successful")
await self.subscribe_to_channels()
elif message_type == "auth_error":
print(f"Authentication failed: {message.get('error')}")
elif message_type == "pong":
# Heartbeat response
pass
else:
await self.process_data_message(message)
async def subscribe_to_channels(self):
subscriptions = [
{"type": "subscribe", "channel": "ticker", "symbol": "BTC/USD"},
{"type": "subscribe", "channel": "orderbook", "symbol": "BTC/USD"},
{"type": "subscribe", "channel": "trades", "symbol": "BTC/USD"}
]
for sub in subscriptions:
await self.websocket.send(json.dumps(sub))
async def handle_reconnect(self):
if self.reconnect_attempts < self.max_reconnect_attempts:
self.reconnect_attempts += 1
delay = self.reconnect_interval * (2 ** (self.reconnect_attempts - 1))
print(f"Reconnecting in {delay}s (attempt {self.reconnect_attempts})")
await asyncio.sleep(delay)
await self.connect()
else:
print("Max reconnection attempts reached")
async def process_data_message(self, message):
# Process incoming data messages
print(f"Received data: {message}")
async def send_ping(self):
if self.websocket:
await self.websocket.send(json.dumps({"type": "ping"}))
async def close(self):
if self.websocket:
await self.websocket.close()
# Usage
async def main():
ws = VibeTradingWebSocket("your_api_key", "your_secret_key")
# Start connection
await ws.connect()
# Set up heartbeat
while True:
await ws.send_ping()
await asyncio.sleep(30)
if __name__ == "__main__":
asyncio.run(main())
Channel Subscriptions
Available Channels
Ticker Channel
Real-time price updates for trading pairs.
Subscribe:
{
"type": "subscribe",
"channel": "ticker",
"symbol": "BTC/USD"
}
Data:
{
"type": "ticker",
"symbol": "BTC/USD",
"price": 49850.25,
"bid": 49840.0,
"ask": 49860.5,
"volume24h": 1250.75,
"change24h": 2.5,
"timestamp": "2024-01-15T12:00:00Z"
}
Order Book Channel
Real-time order book updates.
Subscribe:
{
"type": "subscribe",
"channel": "orderbook",
"symbol": "BTC/USD",
"depth": 20
}
Data:
{
"type": "orderbook",
"symbol": "BTC/USD",
"bids": [
{ "price": 49840.0, "quantity": 0.5 },
{ "price": 49835.0, "quantity": 0.3 }
],
"asks": [
{ "price": 49860.5, "quantity": 0.3 },
{ "price": 49865.0, "quantity": 0.4 }
],
"timestamp": "2024-01-15T12:00:00Z"
}
Trades Channel
Real-time trade executions.
Subscribe:
{
"type": "subscribe",
"channel": "trades",
"symbol": "BTC/USD"
}
Data:
{
"type": "trades",
"symbol": "BTC/USD",
"trades": [
{
"tradeId": "trade_123456",
"price": 49850.25,
"quantity": 0.1,
"side": "buy",
"timestamp": "2024-01-15T12:00:00Z"
}
]
}
Orders Channel
Real-time order updates for your account.
Subscribe:
{
"type": "subscribe",
"channel": "orders"
}
Data:
{
"type": "order_update",
"orderId": "12345678-1234-1234-1234-123456789012",
"status": "filled",
"filledQuantity": 0.1,
"averagePrice": 49850.25,
"timestamp": "2024-01-15T12:00:00Z"
}
Positions Channel
Real-time position updates for your account.
Subscribe:
{
"type": "subscribe",
"channel": "positions"
}
Data:
{
"type": "position_update",
"symbol": "BTC/USD",
"quantity": 0.1,
"unrealizedPnl": 150.75,
"markPrice": 50000.0,
"timestamp": "2024-01-15T12:00:00Z"
}
AI Signals Channel
Real-time AI trading signals.
Subscribe:
{
"type": "subscribe",
"channel": "signals",
"symbols": ["BTC/USD", "ETH/USD"]
}
Data:
{
"type": "signal",
"symbol": "BTC/USD",
"recommendation": "buy",
"confidence": 87,
"timeHorizon": "short_term",
"reasoning": ["Strong bullish momentum detected", "High volume confirmation"],
"timestamp": "2024-01-15T12:00:00Z"
}
Subscription Management
Subscribe to Multiple Channels
{
"type": "subscribe",
"channels": [
{ "channel": "ticker", "symbol": "BTC/USD" },
{ "channel": "orderbook", "symbol": "BTC/USD" },
{ "channel": "trades", "symbol": "BTC/USD" }
]
}
Unsubscribe from Channel
{
"type": "unsubscribe",
"channel": "ticker",
"symbol": "BTC/USD"
}
Unsubscribe from All Channels
{
"type": "unsubscribe_all"
}
Heartbeat and Connection Health
Ping/Pong Mechanism
Maintain connection health with regular ping messages.
Ping Message:
{
"type": "ping"
}
Pong Response:
{
"type": "pong",
"timestamp": "2024-01-15T12:00:00Z"
}
Connection Monitoring
class ConnectionMonitor {
constructor(websocket) {
this.ws = websocket;
this.lastPong = Date.now();
this.pingInterval = 30000; // 30 seconds
this.timeoutThreshold = 60000; // 60 seconds
this.startPing();
this.startMonitoring();
}
startPing() {
setInterval(() => {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({ type: "ping" }));
}
}, this.pingInterval);
}
startMonitoring() {
setInterval(() => {
const timeSinceLastPong = Date.now() - this.lastPong;
if (timeSinceLastPong > this.timeoutThreshold) {
console.warn("Connection timeout detected");
this.handleConnectionTimeout();
}
}, 10000); // Check every 10 seconds
}
handlePong() {
this.lastPong = Date.now();
}
handleConnectionTimeout() {
// Implement reconnection logic
console.log("Attempting to reconnect...");
this.ws.close();
// Trigger reconnection
}
}
Error Handling
Connection Errors
ws.on("error", (error) => {
console.error("WebSocket error:", error);
switch (error.code) {
case "ECONNREFUSED":
console.log("Connection refused - server may be down");
break;
case "ENOTFOUND":
console.log("DNS resolution failed");
break;
case "ETIMEDOUT":
console.log("Connection timeout");
break;
default:
console.log("Unknown connection error");
}
});
Message Processing Errors
function handleMessage(rawMessage) {
try {
const message = JSON.parse(rawMessage);
processMessage(message);
} catch (error) {
console.error("Failed to parse message:", error);
console.log("Raw message:", rawMessage);
}
}
Best Practices
Connection Management
- Reconnection Logic: Implement automatic reconnection with exponential backoff
- Heartbeat Monitoring: Monitor connection health with ping/pong
- Error Handling: Handle all possible connection errors gracefully
- Resource Cleanup: Properly close connections when done
Message Handling
- Message Validation: Validate all incoming messages
- Error Recovery: Handle malformed or unexpected messages
- Rate Limiting: Respect message rate limits
- Memory Management: Avoid memory leaks with large message volumes
Performance Optimization
- Selective Subscriptions: Only subscribe to needed channels
- Message Filtering: Filter messages on the client side
- Connection Pooling: Use connection pooling for multiple streams
- Compression: Enable WebSocket compression when available
Troubleshooting
Common Issues
Connection Refused
- Check URL: Verify WebSocket URL is correct
- Check Network: Ensure network connectivity
- Check Firewall: Verify firewall allows WebSocket connections
- Check SSL: Ensure WSS (secure) connections are supported
Authentication Failures
- Check Credentials: Verify API key and secret are correct
- Check Signature: Ensure signature generation is correct
- Check Timestamp: Verify timestamp is within acceptable range
- Check Permissions: Ensure API key has WebSocket permissions
Message Loss
- Check Buffer: Monitor WebSocket buffer size
- Check Processing: Ensure messages are processed quickly
- Check Reconnection: Verify reconnection logic works correctly
- Check Subscriptions: Ensure subscriptions are maintained after reconnection
Debugging Tools
- Browser DevTools: Use WebSocket tab in browser dev tools
- Wireshark: Monitor WebSocket traffic
- Logging: Implement comprehensive logging
- Health Checks: Monitor connection health metrics
Ready to start streaming data? Check out our WebSocket Events guide or explore Message Formats.