Skip to content

A production-ready WebSocket-based broadcast server in Go for real-time messaging between multiple clients

License

Notifications You must be signed in to change notification settings

letsmakecakes/broadcast-server

Repository files navigation

Broadcast Server

A production-ready WebSocket-based broadcast server and client written in Go. This project enables real-time bidirectional communication between multiple clients through a central server.

Features

  • 🚀 Real-time WebSocket communication
  • 🔄 Automatic message broadcasting to all connected clients
  • 🛡️ Graceful client connection/disconnection handling
  • 📊 Health check and stats endpoints
  • ⚙️ Configurable connection limits
  • 🧪 Comprehensive unit and integration tests
  • 📦 CLI-based interface for easy usage
  • 🔐 Connection pooling and resource management

Architecture

┌─────────┐         ┌─────────────┐         ┌─────────┐
│ Client 1│◄────────┤             ├────────►│ Client 2│
└─────────┘         │   Broadcast │         └─────────┘
                    │    Server   │
┌─────────┐         │   (Hub)     │         ┌─────────┐
│ Client 3│◄────────┤             ├────────►│ Client N│
└─────────┘         └─────────────┘         └─────────┘

The server uses a Hub pattern to manage connections:

  • Hub maintains a registry of all active clients
  • When a message arrives, the Hub broadcasts it to all clients
  • Clients run independent read/write goroutines for concurrent I/O

Installation

Prerequisites

  • Go 1.21 or higher
  • Make (optional, for using Makefile commands)

Clone and Build

# Clone the repository
git clone https://github.com/letsmakecakes/broadcast-server.git
cd broadcast-server

# Install dependencies
make install

# Build the application
make build

Usage

Starting the Server

# Start server on default port (8080)
./broadcast-server start

# Start server on custom port
./broadcast-server start --port 9090

# Start server on custom host and port
./broadcast-server start --host 0.0.0.0 --port 3000

Connecting as a Client

# Connect to default server (localhost:8080)
./broadcast-server connect

# Connect to custom server
./broadcast-server connect --server ws://example.com:8080/ws

# Connect with a username
./broadcast-server connect --username Alice

Using Makefile Commands

# Run server
make run-server

# Run client
make run-client

# Run tests
make test

# Run only unit tests
make test-unit

# Run only integration tests
make test-integration

# Generate coverage report
make test-coverage

# Format code
make fmt

# Run linter
make lint

Configuration

Default configuration can be customized in internal/config/config.go:

Server:
  Host: "localhost"
  Port: "8080"
  ReadTimeout: 10s
  WriteTimeout: 10s
  MaxClients: 100

Client:
  ServerURL: "ws://localhost:8080/ws"
  ReconnectDelay: 5s
  MaxRetries: 3

API Endpoints

WebSocket Endpoint

  • URL: /ws
  • Protocol: WebSocket
  • Description: Main endpoint for client connections

Health Check

  • URL: /health
  • Method: GET
  • Response: 200 OK

Server Stats

  • URL: /stats
  • Method: GET
  • Response: JSON with server statistics
{
  "connected_clients": 5,
  "max_clients": 100,
  "uptime": "1h30m"
}

Message Protocol

Messages are exchanged in JSON format:

{
  "type": "text",
  "content": "Hello, World!",
  "sender": "Alice",
  "timestamp": "2024-01-08T10:30:00Z"
}

Message Types

  • text - Regular chat message
  • join - User joined notification
  • leave - User left notification
  • system - System message
  • error - Error message

Testing

The project includes comprehensive tests:

Unit Tests

Located in *_test.go files alongside source code. Test individual components in isolation.

# Run all unit tests
make test-unit

# Run tests for specific package
go test -v ./pkg/protocol/
go test -v ./internal/server/

Integration Tests

Located in test/integration/. Test the complete system end-to-end.

# Run integration tests
make test-integration

# Skip integration tests
go test -short ./...

Coverage

# Generate coverage report
make test-coverage

# View coverage in browser
open coverage.html

Project Structure

broadcast-server/
├── cmd/
│   └── broadcast-server/
│       └── main.go              # CLI entry point
├── internal/
│   ├── server/
│   │   ├── server.go           # HTTP server & WebSocket handling
│   │   ├── server_test.go      # Server tests
│   │   ├── hub.go              # Connection hub/manager
│   │   └── client.go           # Client connection handler
│   ├── client/
│   │   ├── client.go           # WebSocket client
│   │   └── client_test.go      # Client tests
│   └── config/
│       └── config.go           # Configuration
├── pkg/
│   └── protocol/
│       ├── message.go          # Message definitions
│       └── message_test.go     # Protocol tests
├── test/
│   └── integration/
│       └── integration_test.go # E2E tests
├── Makefile                    # Build automation
├── go.mod                      # Go module definition
├── go.sum                      # Dependency checksums
├── LICENSE                     # MIT license
└── README.md                   # This file

Development

Adding New Features

  1. Create a feature branch
  2. Implement feature with tests
  3. Run make test to verify
  4. Run make fmt and make lint
  5. Submit pull request

Code Style

  • Follow standard Go conventions
  • Run gofmt before committing
  • Add tests for new functionality
  • Document exported functions and types

Examples

Example Server Output

Starting broadcast server on localhost:8080
WebSocket endpoint: ws://localhost:8080/ws
Client registered. Total clients: 1
Client registered. Total clients: 2
Client registered. Total clients: 3

Example Client Session

$ ./broadcast-server connect --username Alice
Connected to server at ws://localhost:8080/ws
Connected! Type your messages (Ctrl+C to quit):
> Hello everyone!
[10:30:15] Alice: Hello everyone!
[10:30:20] Bob: Hi Alice!
[10:30:25] A new user has joined
[10:30:30] Charlie: Hey folks!
>

Performance

  • Handles 100+ concurrent connections (configurable)
  • Low latency message delivery (< 10 ms typical)
  • Efficient memory usage with goroutine pooling
  • Automatic cleanup of disconnected clients

Troubleshooting

Connection Refused

  • Ensure server is running: ./broadcast-server start
  • Check firewall settings
  • Verify the correct port is being used

Max Clients Reached

  • Increase MaxClients in configuration
  • Check for zombie connections
  • Restart the server to clear connections

Messages Not Received

  • Verify the WebSocket connection is active
  • Check network connectivity
  • Review server logs for errors

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Submit a pull request

License

This project is licensed under the MIT License – see the LICENSE file for details.

Acknowledgments

Roadmap

  • Authentication and authorization
  • Message persistence and history
  • Private messaging between clients
  • Message encryption (TLS/SSL)
  • Rooms/channels support
  • Rate limiting
  • Prometheus metrics
  • Docker support
  • Kubernetes deployment configs

Contact

For questions or feedback, please open an issue on GitHub.


Happy Broadcasting! 🚀

About

A production-ready WebSocket-based broadcast server in Go for real-time messaging between multiple clients

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published