WebSockets are a popular protocol for creating real-time communication between a client and a server. This article will guide you through creating a simple chat server using WebSockets in Go, a powerful programming language for building concurrent, scalable applications.

Setting up a Go Workspace

First, make sure you have Go installed on your machine. You can download it from the official Go website. Verify the installation by running:

go version

Next, set up a new Go module for your project:

mkdir chat-server
cd chat-server
go mod init chat-server

Installing the Gorilla WebSocket Package

Go's standard library lacks built-in support for WebSockets. We will use the popular Gorilla WebSocket package. Install it by running:

go get -u github.com/gorilla/websocket

Creating the Server

Now, let's create our chat server. Start by creating a new file named server.go:

package main

import (
    "fmt"
    "net/http"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

func handleConnections(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println("Error upgrading connection:", err)
        return
    }
    defer conn.Close()

    for {
        messageType, message, err := conn.ReadMessage()
        if err != nil {
            fmt.Println("Error reading message:", err)
            break
        }
        fmt.Printf("Received: %s
", message)

        err = conn.WriteMessage(messageType, message)
        if err != nil {
            fmt.Println("Error writing message:", err)
            break
        }
    }
}

func main() {
    http.HandleFunc("/ws", handleConnections)

    go func() {
        if err := http.ListenAndServe(":8080", nil); err != nil {
            fmt.Println("Error starting server:", err)
        }
    }()

    fmt.Println("Server started on :8080")
    select {}
}

In this code snippet, we use Gorilla WebSocket to upgrade HTTP connections to WebSocket connections. The handleConnections function constantly listens for new messages from a connected client and echoes them back.

Running the Server

Use the following command to start your server:

go run server.go

Your WebSocket server is now running on localhost:8080. You can use WebSocket client tools such as websocket.org to test the server by sending and receiving messages.

Testing with a Simple Client

Let's create a simple client in JavaScript to test our server. Use the following HTML and JavaScript code:

<!DOCTYPE html>
<html>
<head><title>WebSocket Client</title></head>
<body>
  <input id="messageInput" type="text" />
  <button onclick="sendMessage()">Send</button>
  <div id="messages"></div>

  <script>
      const socket = new WebSocket('ws://localhost:8080/ws');

      socket.onmessage = function (event) {
          const messagesDiv = document.getElementById('messages');
          const message = document.createElement('div');
          message.textContent = 'Received: ' + event.data;
          messagesDiv.appendChild(message);
      };

      function sendMessage() {
          const input = document.getElementById('messageInput');
          socket.send(input.value);
          input.value = '';
      }
  </script>
</body>
</html>

Open this file in a browser and enter a message. Check if the message appears both in the input and in the received messages area, confirming that both sending and receiving are functioning correctly.

Conclusion

In this article, you've created a basic chat server using WebSockets in Go. You've learned how to set up Go, utilize the Gorilla WebSocket package, handle WebSocket connections on the server side, and interact with the server using a simple JavaScript client. This should provide a solid foundation for more advanced real-time applications using WebSockets.