WebSocket
Real-time communication with your sandbox environment through WebSocket connections. Use this for interactive terminals and file watching.
Overview
The SDK automatically manages WebSocket connections for you. When you use real-time features like terminals or file watching, the connection is established automatically.
Real-Time Terminal
Create interactive terminal sessions:
// Create terminal - WebSocket auto-connects
const terminal = await sandbox.terminal.create({
cols: 120,
rows: 30,
cwd: '/opt/app',
onData: (data) => {
console.log(data); // Real-time output
},
onExit: (code, signal) => {
console.log('Terminal exited:', code);
}
});
// Execute commands
terminal.write('npm install\n');
terminal.write('npm run dev\n');
// Get terminal state (history)
const state = await terminal.getState({
newOnly: false,
maxLines: 100
});
// Decode output
const output = Buffer.from(state, 'base64').toString('utf-8');
console.log(output);
// Resize terminal
await terminal.resize(150, 40);
// Close terminal
await terminal.close();WebSocket connection with query parameter:
const ws = new WebSocket(
`wss://${sandbox.url.replace('https://', '')}/ws?token=${sandbox.token}`
);
ws.onopen = () => {
// Create terminal
ws.send(JSON.stringify({
action: 'terminal_create',
terminalId: 1,
cols: 120,
rows: 30,
cwd: '/opt/app'
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'terminal_data') {
const output = Buffer.from(message.data, 'base64').toString('utf-8');
console.log(output);
}
if (message.type === 'terminal_exit') {
console.log('Exit code:', message.code);
}
};
// Write to terminal
ws.send(JSON.stringify({
action: 'terminal_data',
terminalId: 1,
data: Buffer.from('npm install\n').toString('base64')
}));WebSocket requires a WebSocket client. Using websocat:
# Install websocat first: https://github.com/vi/websocat
# Connect to WebSocket
websocat "wss://sandbox.oblien.com/?token=YOUR_SANDBOX_TOKEN"
# Once connected, send JSON messages:
# Create terminal:
{"action":"terminal_create","terminalId":1,"cols":120,"rows":30,"cwd":"/opt/app"}
# Write to terminal (data must be base64):
{"action":"terminal_data","terminalId":1,"data":"bnBtIGluc3RhbGwK"}Terminal Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
terminalId | number | auto | Terminal ID |
cols | number | 120 | Terminal columns |
rows | number | 30 | Terminal rows |
cwd | string | /opt/app | Working directory |
command | string | - | Initial command |
args | string[] | [] | Command arguments |
task | boolean | false | Run as task (one-off) |
onData | function | - | Data callback |
onExit | function | - | Exit callback |
List Terminals
const terminals = await sandbox.terminal.list();
console.log('Active terminals:', terminals);
terminals.forEach(t => {
console.log(`Terminal ${t.id}`);
});ws.send(JSON.stringify({
action: 'terminal_list'
}));
// Response in ws.onmessage:
// { type: 'terminal_list', terminals: [...] }# Using websocat
websocat "wss://sandbox.oblien.com/?token=YOUR_SANDBOX_TOKEN"
# Send list command:
{"action":"terminal_list"}
# Response: {"type":"terminal_list","terminals":[...]}Complete Terminal Example
// Create interactive terminal
const terminal = await sandbox.terminal.create({
cols: 120,
rows: 30,
cwd: '/opt/app',
onData: (data) => {
// Stream output to console
process.stdout.write(data);
},
onExit: (code, signal) => {
console.log(`\nTerminal exited with code ${code}`);
}
});
console.log(`Created terminal ${terminal.id}`);
// Run commands
terminal.write('npm install\n');
// Wait a bit for install to complete
await new Promise(resolve => setTimeout(resolve, 10000));
// Run development server
terminal.write('npm run dev\n');
// Listen for specific output
terminal.onData((data) => {
if (data.includes('Server running')) {
console.log('Server started successfully!');
}
});
// Get full terminal history
const history = await terminal.getState();
const output = Buffer.from(history, 'base64').toString('utf-8');
console.log('Terminal output:', output);
// Keep terminal running...
// Later, close it
await terminal.close();const ws = new WebSocket(
`wss://${sandbox.url.replace('https://', '')}/ws?token=${sandbox.token}`
);
let terminalId = 1;
ws.onopen = () => {
// Create terminal
ws.send(JSON.stringify({
action: 'terminal_create',
terminalId,
cols: 120,
rows: 30,
cwd: '/opt/app'
}));
// Send commands
setTimeout(() => {
ws.send(JSON.stringify({
action: 'terminal_data',
terminalId,
data: Buffer.from('npm install\n').toString('base64')
}));
}, 1000);
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'terminal_data') {
const output = Buffer.from(message.data, 'base64').toString('utf-8');
console.log(output);
}
if (message.type === 'terminal_exit') {
console.log('Terminal exited:', message.code);
}
};
// Close terminal
ws.send(JSON.stringify({
action: 'terminal_close',
terminalId
}));# Using websocat for interactive terminal
websocat "wss://sandbox.oblien.com/?token=YOUR_SANDBOX_TOKEN"
# Create terminal:
{"action":"terminal_create","terminalId":1,"cols":120,"rows":30,"cwd":"/opt/app"}
# Write commands (base64 encoded):
{"action":"terminal_data","terminalId":1,"data":"bnBtIGluc3RhbGwK"}
# Close terminal:
{"action":"terminal_close","terminalId":1}Execute One-Off Command
For simple command execution without interactive terminal:
// Using terminal manager (WebSocket-based)
const result = await sandbox.terminal.execute({
command: 'npm test',
cwd: '/opt/app',
timeout: 60000
});
console.log('Exit code:', result.exitCode);
console.log('Output:', result.logs);WebSocket Events
Terminal Events
| Event | Description | Data |
|---|---|---|
terminal_data | Terminal output | { data: base64, terminalId } |
terminal_exit | Terminal closed | { code, signal, terminalId } |
terminal_list | List response | { terminals: [...] } |
File Watcher Events
| Event | Description | Data |
|---|---|---|
watch_add | File added | { path } |
watch_change | File changed | { path } |
watch_unlink | File deleted | { path } |
watch_error | Watch error | { path, error } |
Connection Management
// SDK auto-manages connections
// Check connection status
if (sandbox.connected) {
console.log('WebSocket connected');
}
// Manual connect (usually not needed)
await sandbox.connect();
// Manual disconnect
sandbox.disconnect();const ws = new WebSocket(
`wss://${sandbox.url.replace('https://', '')}/ws?token=${sandbox.token}`
);
ws.onopen = () => console.log('Connected');
ws.onclose = () => console.log('Disconnected');
ws.onerror = (error) => console.error('Error:', error);
// Close connection
ws.close();# Using websocat
websocat "wss://sandbox.oblien.com/?token=YOUR_SANDBOX_TOKEN"
# Connection opens automatically
# Close with Ctrl+C or EOFBest Practices
-
Handle connection errors:
terminal.onData((data) => { // Handle output }); -
Clean up terminals: Always close terminals when done
-
Use appropriate buffer sizes: Don't request too much terminal history
-
Handle exit events: Listen for terminal exit to know when commands finish
-
Resize terminals: Match terminal size to display area
Next Steps
- File Watcher - Real-time file monitoring
- Terminal - One-off command execution
- File Operations - Work with files