Skip to content

Namespace API Reference

The Namespace type represents a connection to a specific namespace in Socket.IO. Namespaces allow multiplexing multiple connections over a single WebSocket connection.

Table of Contents

Namespace Concept

Namespaces are separate communication channels that share the same physical connection. They enable:

  • Logical separation: Different areas of your application can use different namespaces
  • Efficiency: A single WebSocket connection handles multiple namespaces
  • Security: You can control access to specific namespaces

Default Namespace

The default namespace is /. When using methods directly on Socket, you are using this namespace:

// These two codes are equivalent
client.On("event", handler)
client.Of("/").On("event", handler)

Obtaining Namespaces

Namespaces are obtained through the Of() method of Socket:

// Get custom namespace
chat := client.Of("/chat")
admin := client.Of("/admin")
notifications := client.Of("/notifications")

Event Methods

On

func (n *Namespace) On(event string, handler EventHandler)

Registers a handler to listen for a specific event on this namespace.

Parameters: - event (string): Event name - handler (EventHandler): Function executed when the event is received

Example:

chat := client.Of("/chat")

chat.On("message", func(data ...interface{}) {
  msg := data[0].(string)
  fmt.Printf("Chat message: %s\n", msg)
})

chat.On("user-joined", func(data ...interface{}) {
  user := data[0].(map[string]interface{})
  fmt.Printf("%s joined the chat\n", user["name"])
})

OnConnect

func (n *Namespace) OnConnect(handler func())

Registers a handler that executes when this namespace successfully connects.

Parameters: - handler (func()): Function executed on connection

Example:

chat := client.Of("/chat")

chat.OnConnect(func() {
  fmt.Println("Connected to namespace /chat")

  // Emit initial event on this namespace
  chat.Emit("join-room", "general")
})

OnDisconnect

func (n *Namespace) OnDisconnect(handler func(reason string))

Registers a handler that executes when this namespace disconnects.

Parameters: - handler (func(reason string)): Function that receives the disconnection reason

Example:

chat := client.Of("/chat")

chat.OnDisconnect(func(reason string) {
  fmt.Printf("Disconnected from /chat: %s\n", reason)
})

Emission Methods

Emit

func (n *Namespace) Emit(event string, data ...interface{}) error

Emits an event to the server on this namespace.

Parameters: - event (string): Event name - data (...interface{}): Arguments to send

Returns: - error: Error if the operation fails

Example:

chat := client.Of("/chat")

// Emit simple message
chat.Emit("message", "Hello everyone")

// Emit structured data
chat.Emit("action", map[string]interface{}{
  "type": "typing",
  "user": "john",
})

// Multiple arguments
chat.Emit("chat-message", "john", "Hello", time.Now().Unix())

EmitWithAck

func (n *Namespace) EmitWithAck(event string, ack AckCallback, data ...interface{}) error

Emits an event and waits for an acknowledgment response from the server on this namespace.

Parameters: - event (string): Event name - ack (AckCallback): Callback function that receives the response - data (...interface{}): Arguments to send

Returns: - error: Error if the operation fails

Example:

chat := client.Of("/chat")

chat.EmitWithAck("get-history", func(response ...interface{}) {
  if response == nil {
    fmt.Println("Timeout waiting for history")
    return
  }

  history := response[0].([]interface{})
  fmt.Printf("History received: %d messages\n", len(history))
}, "general-room")

EmitBinary

func (n *Namespace) EmitBinary(event string, binaryData []byte, data ...interface{}) error

Emits an event with binary data on this namespace.

Parameters: - event (string): Event name - binaryData ([]byte): Binary data to send - data (...interface{}): Additional arguments (optional)

Returns: - error: Error if the operation fails

Example:

chat := client.Of("/chat")

// Read image
imageData, err := os.ReadFile("photo.jpg")
if err != nil {
  log.Fatal(err)
}

// Send image with metadata
chat.EmitBinary("image", imageData, map[string]interface{}{
  "filename": "photo.jpg",
  "from": "user123",
  "size": len(imageData),
})

State Methods

IsConnected

func (n *Namespace) IsConnected() bool

Returns whether this namespace is currently connected.

Returns: - bool: true if connected, false otherwise

Example:

chat := client.Of("/chat")

if chat.IsConnected() {
  chat.Emit("ping")
} else {
  fmt.Println("Chat namespace is not connected")
}

GetPath

func (n *Namespace) GetPath() string

Returns the path of this namespace.

Returns: - string: Namespace path (e.g., /chat, /admin)

Example:

chat := client.Of("/chat")
fmt.Printf("Namespace path: %s\n", chat.GetPath()) // Output: /chat

Examples

Basic Example: Chat Application

package main

import (
  "fmt"
  socketio "github.com/arcaela/socket.io-client-go"
)

func main() {
  client := socketio.New("ws://localhost:3000")
  defer client.Close()

  // Chat namespace
  chat := client.Of("/chat")

  chat.OnConnect(func() {
    fmt.Println("βœ… Connected to chat")

    // Join a room
    chat.Emit("join-room", "general")
  })

  chat.On("message", func(data ...interface{}) {
    username := data[0].(string)
    message := data[1].(string)
    fmt.Printf("πŸ’¬ [%s]: %s\n", username, message)
  })

  chat.On("user-joined", func(data ...interface{}) {
    username := data[0].(string)
    fmt.Printf("πŸ‘€ %s joined the chat\n", username)
  })

  chat.On("user-left", func(data ...interface{}) {
    username := data[0].(string)
    fmt.Printf("πŸ‘‹ %s left the chat\n", username)
  })

  // Send message
  chat.Emit("message", "juan", "Hello everyone!")

  select {}
}

Example: Multiple Namespaces

package main

import (
  "fmt"
  socketio "github.com/arcaela/socket.io-client-go"
)

func main() {
  client := socketio.New("ws://localhost:3000")
  defer client.Close()

  // Public chat namespace
  publicChat := client.Of("/chat")
  publicChat.OnConnect(func() {
    fmt.Println("βœ… Public chat connected")
  })
  publicChat.On("message", func(data ...interface{}) {
    fmt.Printf("πŸ’¬ [Public] %s: %s\n", data[0], data[1])
  })

  // Private chat namespace
  privateChat := client.Of("/chat/private")
  privateChat.OnConnect(func() {
    fmt.Println("βœ… Private chat connected")
  })
  privateChat.On("message", func(data ...interface{}) {
    fmt.Printf("πŸ”’ [Private] %s: %s\n", data[0], data[1])
  })

  // Notifications namespace
  notifications := client.Of("/notifications")
  notifications.OnConnect(func() {
    fmt.Println("βœ… Notifications connected")
  })
  notifications.On("new", func(data ...interface{}) {
    notif := data[0].(map[string]interface{})
    fmt.Printf("πŸ”” Notification: %s\n", notif["message"])
  })

  // Admin namespace (with specific authentication)
  admin := client.Of("/admin")
  admin.OnConnect(func() {
    fmt.Println("βœ… Admin connected")
    admin.Emit("authenticate", map[string]interface{}{
      "token": "admin-secret-token",
    })
  })
  admin.On("stats", func(data ...interface{}) {
    stats := data[0].(map[string]interface{})
    fmt.Printf("πŸ“Š Stats: %v connected users\n", stats["users"])
  })

  select {}
}

Example: Namespace with Acknowledgments

package main

import (
  "fmt"
  "time"
  socketio "github.com/arcaela/socket.io-client-go"
)

func main() {
  client := socketio.New("ws://localhost:3000")
  defer client.Close()

  api := client.Of("/api")

  api.OnConnect(func() {
    fmt.Println("βœ… API namespace connected")

    // Get user data
    api.EmitWithAck("get-user", func(response ...interface{}) {
      if response == nil {
        fmt.Println("⏱️  Timeout waiting for user")
        return
      }

      user := response[0].(map[string]interface{})
      fmt.Printf("πŸ‘€ User: %s\n", user["name"])
    }, "user-123")

    // Create resource
    api.EmitWithAck("create-post", func(response ...interface{}) {
      if response == nil {
        fmt.Println("⏱️  Timeout creating post")
        return
      }

      result := response[0].(map[string]interface{})
      if result["success"].(bool) {
        fmt.Printf("βœ… Post created with ID: %v\n", result["id"])
      } else {
        fmt.Printf("❌ Error: %s\n", result["error"])
      }
    }, map[string]interface{}{
      "title": "My first post",
      "content": "Post content",
    })
  })

  select {}
}

Example: Namespace with Binary Data

package main

import (
  "fmt"
  "os"
  socketio "github.com/arcaela/socket.io-client-go"
)

func main() {
  client := socketio.New("ws://localhost:3000")
  defer client.Close()

  files := client.Of("/files")

  files.OnConnect(func() {
    fmt.Println("βœ… Files namespace connected")

    // Upload file
    uploadFile(files, "document.pdf")
  })

  files.On("upload-progress", func(data ...interface{}) {
    progress := data[0].(map[string]interface{})
    fmt.Printf("πŸ“€ Progress: %.0f%%\n", progress["percent"])
  })

  files.On("upload-complete", func(data ...interface{}) {
    result := data[0].(map[string]interface{})
    fmt.Printf("βœ… File uploaded: %s\n", result["url"])
  })

  files.On("file-received", func(data ...interface{}) {
    binaryData := data[0].([]byte)
    metadata := data[1].(map[string]interface{})

    filename := metadata["filename"].(string)
    fmt.Printf("πŸ“₯ File received: %s (%d bytes)\n", filename, len(binaryData))

    // Save file
    os.WriteFile(filename, binaryData, 0644)
  })

  select {}
}

func uploadFile(ns *socketio.Namespace, path string) {
  data, err := os.ReadFile(path)
  if err != nil {
    fmt.Printf("Error reading file: %v\n", err)
    return
  }

  ns.EmitBinary("upload", data, map[string]interface{}{
    "filename": path,
    "size": len(data),
  })
}

Example: Error Handling per Namespace

package main

import (
  "fmt"
  socketio "github.com/arcaela/socket.io-client-go"
)

func main() {
  client := socketio.New("ws://localhost:3000")
  defer client.Close()

  // Namespace that may require special authentication
  admin := client.Of("/admin")

  admin.OnConnect(func() {
    fmt.Println("βœ… Attempting to authenticate on /admin")
    admin.Emit("auth", map[string]interface{}{
      "token": "admin-token",
    })
  })

  admin.On("auth-success", func(data ...interface{}) {
    fmt.Println("βœ… Authentication successful on /admin")
    admin.Emit("get-stats")
  })

  admin.On("auth-failed", func(data ...interface{}) {
    reason := data[0].(string)
    fmt.Printf("❌ Authentication failed: %s\n", reason)
    admin.Emit("disconnect") // Disconnect this namespace
  })

  admin.On("error", func(data ...interface{}) {
    err := data[0].(string)
    fmt.Printf("⚠️  Error on /admin: %s\n", err)
  })

  admin.OnDisconnect(func(reason string) {
    fmt.Printf("❌ /admin disconnected: %s\n", reason)
  })

  select {}
}

Thread-Safety

All Namespace methods are thread-safe and can be called from multiple goroutines.

chat := client.Of("/chat")

// Emit from multiple goroutines
for i := 0; i < 10; i++ {
  go func(id int) {
    chat.Emit("worker-message", map[string]interface{}{
      "worker": id,
      "data": processData(id),
    })
  }(i)
}

Best Practices

1. Organize by Functionality

// Separate namespaces by functionality
chat := client.Of("/chat")
notifications := client.Of("/notifications")
admin := client.Of("/admin")

2. Verify Connection Before Emitting

chat := client.Of("/chat")

if chat.IsConnected() {
  chat.Emit("message", "Hello")
} else {
  fmt.Println("Chat not connected, queuing message for later")
  queueMessage("Hello")
}

3. Handle Connection Events

api := client.Of("/api")

api.OnConnect(func() {
  // Subscribe to events when connected
  api.Emit("subscribe", []string{"users", "posts", "comments"})
})

api.OnDisconnect(func(reason string) {
  // Clean up state when disconnected
  clearLocalCache()
})

4. Use Acknowledgments for Critical Operations

api := client.Of("/api")

api.EmitWithAck("important-operation", func(response ...interface{}) {
  if response == nil {
    fmt.Println("Operation failed (timeout)")
    retryOperation()
    return
  }

  if response[0].(map[string]interface{})["success"].(bool) {
    fmt.Println("Operation successful")
  }
}, operationData)

See Also