network-ts-sdk/examples/pubsub-chat.ts
2026-01-20 10:41:28 +02:00

141 lines
4.1 KiB
TypeScript

/**
* Pub/Sub Chat Example
*
* Demonstrates a simple chat application using pub/sub with presence tracking.
* Multiple clients can join a room, send messages, and see who's online.
*/
import { createClient } from '../src/index';
import type { PresenceMember } from '../src/index';
interface ChatMessage {
user: string;
text: string;
timestamp: number;
}
async function createChatClient(userName: string, roomName: string) {
const client = createClient({
baseURL: 'http://localhost:6001',
apiKey: 'ak_your_key:default',
});
console.log(`[${userName}] Joining room: ${roomName}...`);
// Subscribe to chat room with presence
const subscription = await client.pubsub.subscribe(roomName, {
onMessage: (msg) => {
try {
const chatMsg: ChatMessage = JSON.parse(msg.data);
const time = new Date(chatMsg.timestamp).toLocaleTimeString();
console.log(`[${time}] ${chatMsg.user}: ${chatMsg.text}`);
} catch {
console.log(`[${userName}] Received: ${msg.data}`);
}
},
onError: (err) => {
console.error(`[${userName}] Error:`, err.message);
},
onClose: () => {
console.log(`[${userName}] Disconnected from ${roomName}`);
},
presence: {
enabled: true,
memberId: userName,
meta: {
displayName: userName,
joinedAt: Date.now(),
},
onJoin: (member: PresenceMember) => {
console.log(`[${userName}] 👋 ${member.memberId} joined the room`);
if (member.meta) {
console.log(`[${userName}] Display name: ${member.meta.displayName}`);
}
},
onLeave: (member: PresenceMember) => {
console.log(`[${userName}] 👋 ${member.memberId} left the room`);
},
},
});
console.log(`[${userName}] ✓ Joined ${roomName}`);
// Send a join message
await sendMessage(client, roomName, userName, 'Hello everyone!');
// Helper to send messages
async function sendMessage(client: any, room: string, user: string, text: string) {
const chatMsg: ChatMessage = {
user,
text,
timestamp: Date.now(),
};
await client.pubsub.publish(room, JSON.stringify(chatMsg));
}
// Get current presence
if (subscription.hasPresence()) {
const members = await subscription.getPresence();
console.log(`[${userName}] Current members in room (${members.length}):`);
members.forEach(m => {
console.log(`[${userName}] - ${m.memberId} (joined at ${new Date(m.joinedAt).toLocaleTimeString()})`);
});
}
return {
client,
subscription,
sendMessage: (text: string) => sendMessage(client, roomName, userName, text),
};
}
async function main() {
const roomName = 'chat:lobby';
// Create first user
const alice = await createChatClient('Alice', roomName);
// Wait a bit
await new Promise(resolve => setTimeout(resolve, 500));
// Create second user
const bob = await createChatClient('Bob', roomName);
// Wait a bit
await new Promise(resolve => setTimeout(resolve, 500));
// Send some messages
await alice.sendMessage('Hey Bob! How are you?');
await new Promise(resolve => setTimeout(resolve, 200));
await bob.sendMessage('Hi Alice! I\'m doing great, thanks!');
await new Promise(resolve => setTimeout(resolve, 200));
await alice.sendMessage('That\'s awesome! Want to grab coffee later?');
await new Promise(resolve => setTimeout(resolve, 200));
await bob.sendMessage('Sure! See you at 3pm?');
await new Promise(resolve => setTimeout(resolve, 200));
await alice.sendMessage('Perfect! See you then! 👋');
// Wait to receive all messages
await new Promise(resolve => setTimeout(resolve, 1000));
// Get final presence count
const presence = await alice.client.pubsub.getPresence(roomName);
console.log(`\nFinal presence count: ${presence.count} members`);
// Leave room
console.log('\nClosing connections...');
alice.subscription.close();
await new Promise(resolve => setTimeout(resolve, 500));
bob.subscription.close();
await new Promise(resolve => setTimeout(resolve, 500));
console.log('\n--- Chat example completed ---');
}
main().catch(console.error);