# WebSocket API Integration

Integrate with the socktop agent's WebSocket API to build custom monitoring tools.

## WebSocket Endpoint

```
ws://HOST:PORT/ws         # Without TLS
wss://HOST:PORT/ws        # With TLS
```

With authentication token (if configured):
```
ws://HOST:PORT/ws?token=YOUR_TOKEN
wss://HOST:PORT/ws?token=YOUR_TOKEN
```

## Request Types

Send JSON messages to request specific metrics:

```json
{"type": "metrics"}       // Fast-changing metrics (CPU, memory, network)
{"type": "disks"}         // Disk information
{"type": "processes"}     // Process list (returns protobuf)
```

## Response Formats

### Metrics (JSON)

```json
{
  "cpu_total": 12.4,
  "cpu_per_core": [11.2, 15.7],
  "mem_total": 33554432,
  "mem_used": 18321408,
  "swap_total": 0,
  "swap_used": 0,
  "hostname": "myserver",
  "cpu_temp_c": 42.5,
  "networks": [{"name":"eth0","received":12345678,"transmitted":87654321}],
  "gpus": [{"name":"nvidia-0","usage":56.7,"memory_total":8589934592,"memory_used":1073741824,"temp_c":65.0}]
}
```

### Disks (JSON)

```json
[
  {"name":"nvme0n1p2","total":512000000000,"available":320000000000},
  {"name":"sda1","total":1000000000000,"available":750000000000}
]
```

### Processes (Protocol Buffers)

Processes are returned in protobuf format, optionally gzip-compressed. Schema:

```protobuf
syntax = "proto3";

message Process {
  uint32 pid = 1;
  string name = 2;
  float cpu_usage = 3;
  uint64 mem_bytes = 4;
}

message ProcessList {
  uint32 process_count = 1;
  repeated Process processes = 2;
}
```

## Example: JavaScript/Node.js

```javascript
const WebSocket = require('ws');

const ws = new WebSocket('ws://localhost:3000/ws');

ws.on('open', function open() {
  console.log('Connected to socktop_agent');
  
  // Request metrics
  ws.send(JSON.stringify({type: 'metrics'}));
  
  // Poll every second
  setInterval(() => {
    ws.send(JSON.stringify({type: 'metrics'}));
  }, 1000);
  
  // Request processes every 3 seconds
  setInterval(() => {
    ws.send(JSON.stringify({type: 'processes'}));
  }, 3000);
});

ws.on('message', function incoming(data) {
  try {
    const jsonData = JSON.parse(data);
    console.log('Received JSON data:', jsonData);
  } catch (e) {
    console.log('Received binary data (protobuf), length:', data.length);
    // Process binary protobuf data with protobufjs
  }
});

ws.on('close', function close() {
  console.log('Disconnected from socktop_agent');
});
```

## Example: Python

```python
import json
import asyncio
import websockets

async def monitor_system():
    uri = "ws://localhost:3000/ws"
    async with websockets.connect(uri) as websocket:
        print("Connected to socktop_agent")
        
        # Request initial metrics
        await websocket.send(json.dumps({"type": "metrics"}))
        
        while True:
            # Request metrics
            await websocket.send(json.dumps({"type": "metrics"}))
            
            # Receive response
            response = await websocket.recv()
            
            try:
                data = json.loads(response)
                print(f"CPU: {data['cpu_total']}%, Memory: {data['mem_used']/data['mem_total']*100:.1f}%")
            except json.JSONDecodeError:
                print(f"Received binary data, length: {len(response)}")
            
            await asyncio.sleep(1)

asyncio.run(monitor_system())
```

## Recommended Intervals

- Metrics: ≥ 500ms
- Processes: ≥ 2000ms
- Disks: ≥ 5000ms

## Handling Protocol Buffers

For processing binary process data:

1. Check if response starts with gzip magic bytes (`0x1f, 0x8b`)
2. Decompress if necessary
3. Parse with protobuf library using the schema above

## Error Handling

Implement reconnection logic with exponential backoff:

```javascript
function connect() {
  const ws = new WebSocket('ws://localhost:3000/ws');
  
  ws.on('open', () => {
    console.log('Connected');
    // Start polling
  });
  
  ws.on('close', () => {
    console.log('Connection lost, reconnecting...');
    setTimeout(connect, 1000);
  });
}

connect();
```

## More Info

For detailed implementation, see the [socktop_agent README](https://github.com/jasonwitty/socktop/tree/master/socktop_agent).