View : 0

12/04/2026 18:16pm

EP.113 Building an Advanced Multi-room Chat System with Go and WebSocket

EP.113 Building an Advanced Multi-room Chat System with Go and WebSocket

#Golang The Series

#redis pubsub

#Multi-room Chat

#WebSocket

#Go

In a typical real-time chat system, users often communicate within a single shared room. But as systems grow — like team chats, support channels, game lobbies, or customer groups we must scale the architecture to support multi-room communication with clear room-level separation and control.

 

This episode will guide you through building a scalable multi-room chat system with production-ready features such as:

  • Room-based message broadcasting
  • Room-level user management
  • Cross-instance communication using Redis Pub/Sub

 

🧩 Multi-room Chat System Architecture

 

Client → WebSocket Gateway → Redis Pub/Sub → Chat Rooms

 

Core Components

  • Room Manager: Handles room creation, deletion, and member tracking
  • Connection Manager: Tracks user connections per room
  • Redis Pub/Sub: Distributes messages across instances for scaling

 

⚙️ Basic Data Structure

 

type Client struct {
	ID     string
	Conn   *websocket.Conn
	RoomID string
}

type Room struct {
	ID      string
	Clients map[*Client]bool
}

 

Room Manager Setup

type RoomManager struct {
	Rooms map[string]*Room
	mu    sync.Mutex
}

func NewRoomManager() *RoomManager {
	return &RoomManager{
		Rooms: make(map[string]*Room),
	}
}

 

💡 Room & Member Management Functions

 

func (rm *RoomManager) JoinRoom(roomID string, client *Client) {
	rm.mu.Lock()
	defer rm.mu.Unlock()

	room, ok := rm.Rooms[roomID]
	if !ok {
		room = &Room{ID: roomID, Clients: make(map[*Client]bool)}
		rm.Rooms[roomID] = room
	}

	room.Clients[client] = true
	client.RoomID = roomID
}

func (rm *RoomManager) LeaveRoom(roomID string, client *Client) {
	rm.mu.Lock()
	defer rm.mu.Unlock()

	if room, ok := rm.Rooms[roomID]; ok {
		delete(room.Clients, client)
		if len(room.Clients) == 0 {
			delete(rm.Rooms, roomID)
		}
	}
}

 

✅ When a user joins a room, the system checks if the room exists if not, it will automatically create it.

 

📡 Broadcasting Messages within a Room

 

func (rm *RoomManager) Broadcast(roomID string, msg string) {
	rm.mu.Lock()
	defer rm.mu.Unlock()

	if room, ok := rm.Rooms[roomID]; ok {
		for c := range room.Clients {
			c.Conn.WriteMessage(websocket.TextMessage, []byte(msg))
		}
	}
}

 

✅ All users in the same room will receive messages in real-time.

 

🔄 Scaling with Redis Pub/Sub

 

When you deploy multiple server instances, you'll need to synchronize messages across them. That’s where Redis Pub/Sub comes in.

 

func subscribeRedis(rm *RoomManager, rdb *redis.Client) {
	sub := rdb.Subscribe(context.Background(), "chat_channel")
	for msg := range sub.Channel() {
		var data struct {
			RoomID  string `json:"room_id"`
			Message string `json:"message"`
		}
		json.Unmarshal([]byte(msg.Payload), &data)
		rm.Broadcast(data.RoomID, data.Message)
	}
}

func publishMessage(rdb *redis.Client, roomID, msg string) {
	data, _ := json.Marshal(map[string]string{
		"room_id": roomID,
		"message": msg,
	})
	rdb.Publish(context.Background(), "chat_channel", data)
}

 

✅ Now, no matter which server a user is connected to, the message will reach all clients across all machines.

 

🧠 Advanced Optimization Tips

 

CategoryRecommendations
ScalabilityUse Redis or NATS for message distribution
Room TypesSupport types like global, private, team
User ManagementStore per-room users in Redis hash
PersistenceSave chat messages to a database
MonitoringTrack metrics such as connections per room

 

🚀 Challenge: Build Your Own!

 

Try building your own multi-room chat system using Go + WebSocket, and integrate Redis Pub/Sub to support distributed message broadcasting.

Mastering this architecture means you're ready to build enterprise-grade real-time chat systems!

 


 

🌟 Coming Next: EP.114 Multi-device & Multi-session Management

 

In the next episode, we’ll explore how to manage multiple devices and sessions per user, design seamless session control, prevent duplication, and support safe, concurrent access across mobile and desktop all over WebSocket! 📱💻