Golang WebSocket creates a separate session

Introduction

In Internet applications, real-time communication is a very important feature. WebSocket is a TCP-based protocol that allows bidirectional communication between clients and servers. Golang is a high-performance programming language that provides native support for WebSocket, making it very simple to create WebSocket sessions in Golang. This article will introduce how to use Golang to create a separate WebSocket session to achieve real-time communication functionality.

Introduction to WebSocket

WebSocket is a protocol for full-duplex communication over a single TCP connection. It is different from the traditional HTTP protocol, which is a stateless protocol and each request requires the establishment of a new connection. WebSocket establishes a persistent connection between the client and the server, enabling real-time two-way communication.

The handshake of the WebSocket protocol is completed through an HTTP request. After the handshake, the connection between the client and the server will remain open and arbitrary data can be sent and received. WebSocket uses an event-like mechanism. When a new message arrives, the server can actively push it to the client without the client actively sending a request.

WebSocket support in Golang

Golang provides the net/http package to handle HTTP requests and responses, and also provides the gorilla/websocket library to implement support for the WebSocket protocol. gorilla/websocket is a very popular third-party library that provides a high-level encapsulation of the WebSocket protocol, making it easier to create WebSocket sessions in Golang.

Before we begin, we first need to install the gorilla/websocket library. It can be installed using the following command:

go get github.com/gorilla/websocket

Once the installation is complete, we can start creating WebSocket sessions.

Create WebSocket server

First, we need to create a WebSocket server that receives connection requests from clients and handles WebSocket sessions. Here is a simple WebSocket server example:

package main

import (
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

//Create an upgrader object to upgrade the HTTP connection to the WebSocket connection
var upgrader = websocket.Upgrader{<!-- -->
    ReadBufferSize: 1024,
    WriteBufferSize: 1024,
}

func main() {<!-- -->
    http.HandleFunc("/ws", handleWebSocket)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func handleWebSocket(w http.ResponseWriter, r *http.Request) {<!-- -->
    //Upgrade HTTP connection to WebSocket connection
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {<!-- -->
        log.Println("Upgrade failed:", err)
        return
    }

    defer conn.Close()

    // Handle WebSocket session
    for {<!-- -->
        //Read the message sent by the client
        messageType, message, err := conn.ReadMessage()
        if err != nil {<!-- -->
            log.Println("Read message failed:", err)
            break
        }

        // Process messages sent by the client
        log.Printf("Received message: %s", message)

        //Reply to client message
        err = conn.WriteMessage(messageType, message)
        if err != nil {<!-- -->
            log.Println("Write message failed:", err)
            break
        }
    }
}

In the above example, we first create an upgrader object, which is used to upgrade an HTTP connection to a WebSocket connection. Then, we define a handleWebSocket function to handle WebSocket sessions. In this function, we first upgrade the HTTP connection to a WebSocket connection, and then enter an infinite loop to continuously read the messages sent by the client and reply to the client with the same message.

Finally, we use the http.HandleFunc function to map the /ws path to the handleWebSocket function, and then call http.ListenAndServe Function to start the WebSocket server.

Create WebSocket client

Next, we need to create a WebSocket client that sends WebSocket requests to the server and handles messages pushed by the server. Here is a simple WebSocket client example:

package main

import (
    "log"
    "os"
    "os/signal"
    "time"

    "github.com/gorilla/websocket"
)

func main() {<!-- -->
    //Create a dialer object for establishing a WebSocket connection
    dialer := websocket.Dialer{<!-- -->
        HandshakeTimeout: 10 * time.Second,
    }

    // Establish WebSocket connection
    conn, _, err := dialer.Dial("ws://localhost:8080/ws", nil)
    if err != nil {<!-- -->
        log.Fatal("Dial failed:", err)
    }
    defer conn.Close()

    // Start a goroutine to receive messages pushed by the server
    go func() {<!-- -->
        for {<!-- -->
            _, message, err := conn.ReadMessage()
            if err != nil {<!-- -->
                log.Println("Read message failed:", err)
                break
            }

            log.Printf("Received message: %s", message)
        }
    }()

    //Send message to server
    message := []byte("Hello, WebSocket!")
    err = conn.WriteMessage(websocket.TextMessage, message)
    if err != nil {<!-- -->
        log.Println("Write message failed:", err)
        return
    }

    // Wait for the user to press Ctrl + C to terminate the program
    interrupt := make(chan os.Signal, 1)
    signal.Notify(interrupt, os.Interrupt)
    <-interrupt
}

In the above example, we first create a dialer object, which is used to establish a WebSocket connection. Then, we use the dialer.Dial function to establish a WebSocket connection and specify the server’s address as ws://localhost:8080/ws. We then use the conn.WriteMessage function to send a message to the server and a goroutine to receive messages pushed by the server.

Finally, we use the signal.Notify function to register a signal listener. When the user presses Ctrl + C, the program will receive an interrupt signal, and then the program will exit.

Create a separate session

In practical applications, we may need to create a separate session for each client in order to manage and track the client’s status. In Golang, this can be achieved by creating a separate goroutine for each WebSocket connection. Here is an example:

package main

import (
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{<!-- -->
    ReadBufferSize: 1024,
    WriteBufferSize: 1024,
}

func main() {<!-- -->
    http.HandleFunc("/ws", handleWebSocket)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func handleWebSocket(w http.ResponseWriter, r *http.Request) {<!-- -->
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {<!-- -->
        log.Println("Upgrade failed:", err)
        return
    }

    defer conn.Close()

    //Create a separate session
    session := NewSession()

    // handle session
    session.Handle(conn)
}

type Session struct {<!-- -->
    conn *websocket.Conn
}

func NewSession() *Session {<!-- -->
    return &Session{<!-- -->}
}

func (s *Session) Handle(conn *websocket.Conn) {<!-- -->
    s.conn = conn

    go s.readLoop()
    go s.writeLoop()
}

func (s *Session) readLoop() {<!-- -->
    for {<!-- -->
        messageType, message, err := s.conn.ReadMessage()
        if err != nil {<!-- -->
            log.Println("Read message failed:", err)
            break
        }

        log.Printf("Received message: %s", message)
    }
}

func (s *Session) writeLoop() {<!-- -->
    for {<!-- -->
        select {<!-- -->
        // Get the message from the message queue and send it to the client
        case message := <-s.messageQueue:
            err := s.conn.WriteMessage(websocket.TextMessage, message)
            if err != nil {<!-- -->
                log.Println("Write message failed:", err)
            }
        }
    }
}

In the above example, we first define a Session structure, which contains a WebSocket connection. Then, we create a NewSession function that creates a new session object. The session object has two important methods: Handle method

Scene

Golang’s WebSocket can be used to create separate sessions and is suitable for many scenarios. The following is an introduction to a usage scenario:

Scenario: Online chat room

In an online chat room, users can communicate with other users in real time via WebSocket. Each user can create an individual conversation, chat privately with other users or send messages in groups.

Usage scenario description:

  1. Users enter the chat room and enter their nickname and chat content on the front-end page.
  2. The front-end page establishes a connection with the back-end Golang server through WebSocket.
  3. The backend server uses Golang’s WebSocket package to handle the client’s connection request.
  4. When a user sends a message, the front-end page sends the message to the back-end server via WebSocket.
  5. After the backend server receives the message, it broadcasts it to all online users, or only to specific users as needed.
  6. Each connected client can receive messages sent by other users and display them on the front-end page.

In this scenario, Golang’s WebSocket enables real-time communication between users and maintains the session independence of each user. It can handle concurrent connections, allowing multiple users to chat at the same time without interfering with each other.

It is worth noting that Golang’s WebSocket can also ensure the security of chat rooms by adding necessary security and authentication mechanisms. For example, you can use SSL/TLS to encrypt the connection, or use tokens for user authentication. These security measures ensure that users’ chat content and personal information are protected.