08/05/2026 06:52am

EP.114 Managing Multi-device & Multi-session in WebSocket Systems
#Real-time Application
#Go
#Multi-session
#Multi-device
#WebSocket Server
#WebSocket
In real-world real-time applications such as chat systems, notifications, or online games, a single user might log in from multiple devices simultaneously, like a mobile phone and a desktop 💻📱
If your WebSocket system doesn't handle multi-device or multi-session properly, you may face issues like delayed synchronization, duplicate messages, or session leaks.
In this episode, you'll learn how to build a WebSocket system that:
- Supports multiple active devices per user
- Manages independent sessions securely
- Syncs data across devices in real time
- Is production-ready for real-world scale 🚀
🔍 Common Problems with Multiple Sessions
| Problem | Description |
|---|---|
| Duplicate Sessions | The same user opens multiple devices → duplicate messages appear |
| Connection Leak | Previous sessions not closed when a new device connects |
| Expired Token | Poor refresh token handling causes disconnection |
| Slow Sync | Delayed data updates across devices |
✅ A solid system should give each device its own session, but ensure synchronized data across all.
🧩 WebSocket Session Structure
type Session struct {
UserID string
DeviceID string
Connection *websocket.Conn
}
var (
activeSessions = make(map[string]map[string]*Session) // userID → deviceID → session
mu sync.Mutex
)
✅ One user can have multiple devices
✅ Each device has its own session
✅ You can send messages to specific devices or broadcast to all
🔌 Handling Connections from Multiple Devices
func handleConnection(w http.ResponseWriter, r *http.Request) {
conn, _ := upgrader.Upgrade(w, r, nil)
userID := r.URL.Query().Get("user_id")
deviceID := r.URL.Query().Get("device_id")
mu.Lock()
if activeSessions[userID] == nil {
activeSessions[userID] = make(map[string]*Session)
}
activeSessions[userID][deviceID] = &Session{
UserID: userID,
DeviceID: deviceID,
Connection: conn,
}
mu.Unlock()
defer func() {
mu.Lock()
delete(activeSessions[userID], deviceID)
if len(activeSessions[userID]) == 0 {
delete(activeSessions, userID)
}
mu.Unlock()
conn.Close()
}()
for {
_, msg, err := conn.ReadMessage()
if err != nil {
break
}
log.Printf("[%s-%s]: %s", userID, deviceID, msg)
}
}
✅ When a device disconnects, its session is removed
✅ No stale sessions remain in the system
🔐 Token & Session Validation
func validateToken(token string) (string, error) {
claims := &jwt.StandardClaims{}
_, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) {
return []byte("SECRET_KEY"), nil
})
if err != nil {
return "", err
}
return claims.Subject, nil
}
- Each device should have its own access token
- Refresh tokens should be handled per device
- If a token expires → disconnect only that session
🌐 Real-time Sync Across Devices
func syncToAllDevices(userID string, message string) {
mu.Lock()
defer mu.Unlock()
for _, session := range activeSessions[userID] {
session.Connection.WriteMessage(websocket.TextMessage, []byte(message))
}
}
✅ Send a message from mobile → it appears on desktop instantly
✅ Achieve real-time sync across all devices
✅ Fully ready for production-scale applications
🧱 Production-level Recommendations
| Category | Recommendation |
|---|---|
| Session Storage | Use Redis or a database to persist session state |
| Security | Bind tokens to specific device IDs |
| Sync | Use Redis Pub/Sub to distribute updates |
| Timeout | Automatically remove sessions after idle timeout |
| Monitoring | Track the number of connected devices per user |
🚀 Ready for a Challenge?
Try building a system where: One user logs in from both mobile and desktop → Sends a message from one device → Instantly appears on the other
If you pull this off, you're building like the pros do in real production environments ✅
🌟 Coming Next: Advanced Multiplayer Game Systems (EP.115)
In EP.115, we’ll enter the world of real-time multiplayer games.
Learn how to sync player state, events, and positions across all users using Go and WebSocket so you're ready to build next-gen interactive gaming platforms 🎮