Version: 1.0.0 Category: Authentication / Streaming Purpose: Connection, subscription, message handling, and reconnection examples for NATS
Structs uses NATS messaging (via GRASS) for real-time game state streaming. Clients can connect using the native NATS protocol or a WebSocket wrapper. This document covers connection setup, subject subscription, message processing, and reconnection handling with code examples in JavaScript and Python.
Connect directly to the NATS server using the native protocol. Authentication is optional.
Connection URL: nats://localhost:4222
JavaScript:
import { connect } from 'nats';
const nc = await connect({
servers: ['nats://localhost:4222']
});
Python:
import asyncio
from nats.aio.client import Client as NATS
nc = NATS()
await nc.connect('nats://localhost:4222')
After connecting, subscribe to the desired subjects for real-time updates.
Connect using the WebSocket wrapper for browser-based clients.
Connection URL: ws://localhost:1443
const ws = new WebSocket('ws://localhost:1443');
ws.onopen = () => {
ws.send(JSON.stringify({
action: 'subscribe',
subjects: ['structs.player.1']
}));
};
After the connection opens, send a subscribe message to begin receiving updates.
Subscribe to NATS subjects to receive real-time updates for specific entities.
Available subjects:
structs.player.1 – Player-specific updatesstructs.planet.1-1 – Planet-specific updatesstructs.global – Global game state updatesJavaScript:
const playerSub = nc.subscribe('structs.player.1', {
callback: (err, msg) => {
if (err) {
console.error('Error:', err);
return;
}
const data = JSON.parse(msg.data.toString());
handlePlayerUpdate(data);
}
});
Python:
async def player_handler(msg):
data = json.loads(msg.data.decode())
handle_player_update(data)
await nc.subscribe('structs.player.1', cb=player_handler)
When a message arrives, it contains a subject and data payload. Process messages by parsing the data, validating the format, updating local game state, and then acting on the update.
Example message:
{
"subject": "structs.player.1",
"data": {
"id": "1",
"primaryAddress": "structs1abc...",
"playerId": "1",
"updatedAt": "2025-01-XX 12:00:00"
}
}
Message handling steps:
JavaScript:
function handlePlayerUpdate(data) {
gameState.players[data.id] = data;
processPlayerUpdate(data);
}
If the connection to NATS is lost, implement reconnection with exponential backoff and re-subscribe to all subjects after reconnecting.
JavaScript:
nc.closed().then(() => {
console.log('Connection closed, reconnecting...');
setTimeout(async () => {
nc = await connect({ servers: ['nats://localhost:4222'] });
await resubscribeAll();
}, 2000);
});
Reconnection procedure: