# Sockets – Real-time Communication
The Collab Server offers comprehensive real-time features via sockets.
## Connection
```typescript
import { io } from 'socket.io-client';
const socket = io('http://localhost:4000', {
query: {
room: 'artwork:item-001',
artworkId: 'item-001'
}
});
```
## Room Structure
| Room | Purpose | Clients |
|----------------|-------------------|--------------------|
| `studio` | Studio UI | Art.Works! Studio |
| `artwork:{id}` | Artwork instance | Artwork in browser |
| `logs` | Central logging | All clients |
### Joining a Room
```typescript
socket.emit('join-room', { room: 'artwork:item-001' });
```
## Communication Modes
### 1. Artwork ↔ Artwork
Direct communication between artworks:
```typescript
// Send
socket.emit('artwork:message', {
type: 'custom-event',
payload: { x: 100, y: 200 },
targetRoom: 'artwork:item-002'
});
// Receive
socket.on('artwork:message', (data) => {
console.log(data.payload);
});
```
### 2. Studio ↔ Artwork
Debugging and parameter control:
```typescript
// Studio requests parameters
socket.emit('request-parameter-dump', {
targetRoom: 'artwork:item-001'
});
// Artwork sends parameters
socket.on('request-parameter-dump', () => {
socket.emit('parameter-dump', {
type: 'parameter-dump',
payload: tweakpane.exportState(),
artworkId: 'item-001'
});
});
```
### 3. Multi-Screen Entity Transfer
Transfer entities between screens:
```typescript
// Entity exits screen on the right
socket.emit('entity:transfer', {
entity: entityData,
direction: 'right',
sourceScreen: 'screen-1'
});
// Neighbor screen receives entity
socket.on('entity:receive', (data) => {
spawnEntity(data.entity, 'left');
});
```
### 4. Input Broadcast
Shared inputs for all artworks:
```typescript
// Broadcast mouse position
socket.emit('input:broadcast', {
type: 'mouse',
x: mouseX,
y: mouseY
});
// All artworks receive
socket.on('input:broadcast', (data) => {
sharedMouse.x = data.x;
sharedMouse.y = data.y;
});
```
## Event Types
### Control Events
| Event | Direction | Description |
|--------------------------|------------------|------------------------------|
| `studio:command` | Studio → Artwork | Commands (pause, play, reset)|
| `request-parameter-dump` | Studio → Artwork | Request parameters |
| `parameter-dump` | Artwork → Studio | Send parameters |
### Data Events
| Event | Direction | Description |
|-------------------|-------------------|------------------|
| `artwork:message` | Artwork ↔ Artwork | Custom messages |
| `input:broadcast` | Any → All | Shared input |
| `entity:transfer` | Artwork → Server | Entity transfer |
| `entity:receive` | Server → Artwork | Receive entity |
### System Events
| Event | Description |
|--------------|------------------------|
| `connect` | Connection established |
| `disconnect` | Connection terminated |
| `error` | Error occurred |
## Topology
For multi-screen installations:
```typescript
socket.emit('topology:configure', {
screens: [
{ id: 'screen-1', neighbors: { right: 'screen-2' } },
{ id: 'screen-2', neighbors: { left: 'screen-1', right: 'screen-3' } },
{ id: 'screen-3', neighbors: { left: 'screen-2' } }
]
});
```
## Logging
Central log system:
```typescript
// Send log
socket.emit('log', {
level: 'info',
message: 'Artwork started',
artworkId: 'item-001',
timestamp: Date.now()
});
// Receive logs (Studio)
socket.on('log', (data) => {
console.log(`[${data.artworkId}] ${data.message}`);
});
```
## Connection Status
```typescript
socket.on('connect', () => {
console.log('Connected:', socket.id);
});
socket.on('disconnect', (reason) => {
console.log('Disconnected:', reason);
});
socket.on('connect_error', (error) => {
console.error('Connection error:', error);
});
```
## Best Practices
1. **Work room-based** – Don't broadcast globally
2. **Minimize payload** – Only send necessary data
3. **Throttling** – Throttle high-frequency events
4. **Reconnect logic** – Reconnect automatically
5. **Error handling** – Catch and log errors