Logo

dev-resources.site

for different kinds of informations.

Real-Time Web Application demo with WebSocket - Backend

Published at
12/27/2024
Categories
websocket
go
Author
tom-takeru
Categories
2 categories in total
websocket
open
go
open
Author
10 person written this
tom-takeru
open
Real-Time Web Application demo with WebSocket - Backend

Introduction

In this article, I will explore the backend implementation of my real-time WebSocket application. Built using Gin and Go, the backend efficiently manages WebSocket connections, stores messages, and broadcasts updates to all connected clients.


Project Structure

https://github.com/tom-takeru/web-socket-demo

My backend project is organized to ensure modularity and reusability. Below is the updated directory structure:

./backend
├── go.mod
├── go.sum
├── main.go
└── stores
    └── messages.go
Enter fullscreen mode Exit fullscreen mode

Key Directories and Files

  • go.mod: Defines module dependencies and versions.
  • main.go: Entry point of the application that initializes the WebSocket server and routes.
  • stores/messages.go: Manages message storage with thread-safe operations.

Core Component: main.go

main.go is the main entry point for my WebSocket server application. It sets up the Gin router, defines the WebSocket route, and handles the WebSocket lifecycle.

Code Walkthrough

package main

import (
    "encoding/json"
    "net/http"
    "sync"
    "time"

    "github.com/gin-gonic/gin"
    "github.com/gorilla/websocket"

    "github.com/tom-takeru/web-socket-demo/backend/stores"
)

var (
    upgrader = websocket.Upgrader{
        CheckOrigin: func(r *http.Request) bool {
            origin := r.Header.Get("Origin")
            // NOTE: This project is for local development only.
            return origin == "http://localhost:3000"
        },
    }
    messageStore = stores.NewMessageStore()
    clients      = make(map[*websocket.Conn]bool)
    clientsMu    sync.Mutex
)

func handleWebSocket(c *gin.Context) {
    conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to upgrade to WebSocket"})
        return
    }
    defer conn.Close()

    clientsMu.Lock()
    clients[conn] = true
    clientsMu.Unlock()

    // Send existing messages to the new connection
    for _, msg := range messageStore.MarshalMessages() {
        conn.WriteMessage(websocket.TextMessage, msg)
    }

    for {
        _, message, err := conn.ReadMessage()
        if err != nil {
            break
        }

        var msgData map[string]string
        if err := json.Unmarshal(message, &msgData); err != nil {
            break
        }

        timestamp := time.Now().Format(time.RFC3339)
        msgData["timestamp"] = timestamp

        messageStore.AddMessage(msgData)

        modifiedMessage, err := json.Marshal(msgData)
        if err != nil {
            break
        }

        clientsMu.Lock()
        for client := range clients {
            if err := client.WriteMessage(websocket.TextMessage, modifiedMessage); err != nil {
                client.Close()
                delete(clients, client)
            }
        }
        clientsMu.Unlock()
    }

    clientsMu.Lock()
    delete(clients, conn)
    clientsMu.Unlock()
}

func main() {
    r := gin.Default()
    r.GET("/ws", handleWebSocket)
    r.Run("localhost:8080")
}
Enter fullscreen mode Exit fullscreen mode

Key Functionalities

  1. State Management: Tracks connected clients and ensures thread-safe access using a mutex.
  2. WebSocket Lifecycle: Handles connection setup, message broadcasting, and cleanup on disconnection.

Conclusion

The backend implementation of my WebSocket demo application demonstrates how to manage real-time communication effectively using Gin and Go. By leveraging WebSocket for persistent connections and a thread-safe message store, this application serves as a robust foundation for building real-time web applications.

In the next article, I will discuss deployment strategies and optimizing WebSocket performance.


Links to the Series

websocket Article's
30 articles in total
Favicon
Unchain Proxy Svr By Golang
Favicon
Getting Started with Web Sockets in Node.js
Favicon
Implementing a Scalable Forex WebSocket Using a Python Proxy
Favicon
Building SyncBridge: When "Copy Here, Paste There" Gets an Upgrade 🚀
Favicon
Socket.IO vs. WebSocket: Pros and Cons for Beginners
Favicon
Building Real-Time Dashboards with WebSockets: A Crypto Live Trades Example
Favicon
WebSocket Load Testing: A Comprehensive Guide to Seamless API Performance
Favicon
Real-Time Web Application demo with WebSocket - Backend
Favicon
Real-Time Web Application demo with WebSocket - Frontend
Favicon
Real-Time Web Application demo with WebSocket - Overview
Favicon
WebSocket Integration in React for Real-Time Communication
Favicon
How to disconnect WebSocket from Chrome Developer tool
Favicon
Guarantee message deliveries for real-time WebSocket APIs with Serverless on AWS
Favicon
WebSockets: The Secret to Seamless Real-Time Communication
Favicon
WebSocket broadcasting with JavaScript and Bun
Favicon
WebSocket Client with JavaScript
Favicon
A Strategy Template Allows You to Use WebSocket Market Seamlessly
Favicon
WebSocket with JavaScript and Bun
Favicon
Top 10 WebSocket Testing Tools for Real-Time Apps (Updated 2024)
Favicon
AWS AppSync Events — Serverless WebSockets Done Right or Just Different?
Favicon
How to Get Free Market Data: Mastering The Market Data Feed Via Free API Key
Favicon
SimplySocket: A Lightweight WebSocket Wrapper for Go
Favicon
Building Simple Real-Time System Monitor using Go, HTMX, and Web Socket
Favicon
Synchronizing Collaborative Text Editing with Yjs and WebSockets
Favicon
Scaling Kafka with WebSockets
Favicon
Building Tetris using WebSocket and Svelte Stores
Favicon
Mastering WebSocket Load Balancing: Unlocking Resilience with Sticky IPs and Session Routing
Favicon
What is WebRTC and How Does It Work?
Favicon
6 Ways Handle WebSocket Load Balancing Without Losing the Connection Thread
Favicon
6 Ways Handle WebSocket Load Balancing Without Losing the Connection Thread

Featured ones: