如何在GUN中处理连接/断开状态、获取在线用户并触发状态回调
Hey Ivan, great questions about GUN's connection handling and user presence features! Let's break this down step by step:
1. Tracking Connection/Disconnection States
GUN has built-in event listeners that make it straightforward to monitor when your client (or server) connects to or loses connection with GUN peers/nodes. Here are the key approaches:
Global Connection Status: Use the
upanddownevents on your main GUN instance. Theupevent fires when a connection to a node is established, whiledowntriggers when all connections are lost:const gun = GUN(); // Triggered when connection is established gun.on('up', () => { console.log('Successfully connected to GUN network'); }); // Triggered when all connections are lost gun.on('down', () => { console.log('Disconnected from GUN network'); });Per-Peer Status: If you need to track individual peer connections (useful for multi-node setups), listen to the
peerevent and then monitor the peer'sopen/closeevents:gun.on('peer', (peer) => { // Peer connection opened peer.on('open', () => { console.log(`Connected to peer: ${peer.url}`); }); // Peer connection closed peer.on('close', () => { console.log(`Disconnected from peer: ${peer.url}`); }); });
2. Getting Online Users (User Presence)
To track online users, you'll want to maintain a shared "online users" node in GUN, where users register their presence when they connect, and GUN automatically cleans up their entry when they disconnect. Here's how to implement this:
Step 1: Register User on Login/Connect
Once a user authenticates (using GUN's built-in user().auth()), write their presence to a public node with the ephemeral option set to true—this ensures the entry is removed when the user disconnects:
const gun = GUN(); const user = gun.user(); // Authenticate the user user.auth('your-username', 'your-password', (ack) => { if (ack.err) { console.error('Auth failed:', ack.err); return; } // Register user presence in the online list gun.get('onlineUsers').get(user._.pub).put({ username: user._.alias, // Or use your own username field lastSeen: Date.now() }, { opt: { ephemeral: true } }); });
Step 2: Listen for Online User Changes
To get real-time updates of who's online, map over the onlineUsers node and listen for changes:
// Monitor online users in real-time gun.get('onlineUsers').map().on((userData, userId) => { if (userData) { console.log(`✅ User ${userData.username} is online`); } else { console.log(`❌ User ${userId} went offline`); } });
3. Executing Custom Functions on Connect/Disconnect (Push Notifications)
Absolutely! You can hook into the same up/down (or peer open/close) events to run custom code—like pushing connection status alerts to users. Here are examples for different contexts:
Frontend Browser Notifications
If you're building a web app, use the browser's Notification API to alert users when their connection status changes:
// Request notification permission first (do this on user interaction) document.getElementById('request-notifications').addEventListener('click', () => { Notification.requestPermission(); }); // Push alert on connection gun.on('up', () => { if (Notification.permission === 'granted') { new Notification('Connection Update', { body: 'You\'re now connected to the server!', icon: '/path/to/icon.png' }); } }); // Push alert on disconnection gun.on('down', () => { if (Notification.permission === 'granted') { new Notification('Connection Update', { body: 'You\'ve lost connection to the server. Check your network.', icon: '/path/to/warning-icon.png' }); } });
Server-Side or Cross-User Notifications
If you want to notify other users when someone connects/disconnects, update a public connectionAlerts node in the up/down event callbacks, and have other clients listen to that node:
// On server/client, when connection is established gun.on('up', () => { gun.get('connectionAlerts').put({ message: 'Server connection restored', timestamp: Date.now(), type: 'success' }); }); // Other clients listen for alerts gun.get('connectionAlerts').on((alert) => { // Display the alert to the user (e.g., show a toast message) showToast(alert.message, alert.type); });
内容的提问来源于stack exchange,提问作者Ivan Kalashnik

