В мире коммуникации в реальном времени WebSockets — это невоспетые герои, которые обеспечивают плавный двунаправленный обмен данными между клиентом и сервером. В сочетании с эффективностью и простотой языка программирования Go вы получаете мощный набор инструментов для создания надёжных и интерактивных приложений.

В этой статье мы подробно рассмотрим процесс создания чат-бота на Go с использованием WebSockets, чтобы вы получили удовольствие от процесса и были в курсе всех подробностей. Перед тем как погрузиться в код, убедитесь, что у вас есть следующие предварительные условия:

  • Установлен Go: если вы новичок в Go, то можете скачать его с официального сайта Go.
  • Базовый синтаксис Go: если вам нужно освежить знания, вот [рекомендованная книга][1], которая поможет вам начать работу.
  • Docker (необязательно): для контейнеризации, но здесь мы не будем углубляться в эту тему.

Шаг 1: Настройка HTTP-сервера

Чтобы начать, нам нужен простой HTTP-сервер для размещения нашего чат-приложения. Вот как вы можете его настроить:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "frontend/index.html")
    })

    log.Println("HTTP server started on :8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

Этот код настраивает HTTP-сервер, который обслуживает файл index.html из каталога frontend.

Шаг 2: Создание интерфейса

Давайте создадим простой интерфейс для взаимодействия с нашим чат-ботом. Вот базовый файл index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Чатбот</title>
    <style>
        #messages {
            height: 300px;
            overflow-y: scroll;
        }
    </style>
</head>
<body>
    <h1>Чатбот</h1>
    <input id="username" type="text" placeholder="Username">
    <input id="message" type="text" placeholder="Message">
    <button id="send">Отправить</button>
    <div id="messages"></div>

    <script>
        const usernameInput = document.querySelector('#username');
        const messageInput = document.querySelector('#message');
        const sendButton = document.querySelector('#send');
        const messagesDiv = document.querySelector('#messages');

        const ws = new WebSocket("ws://" + window.location.host + "/ws");

        ws.onmessage = function(event) {
            const message = JSON.parse(event.data);
            const messageElement = document.createElement('div');
            messageElement.textContent = `${message.username}: ${message.content}`;
            messagesDiv.appendChild(messageElement);
        };

        sendButton.onclick = () => {
            const message = {
                username: usernameInput.value,
                content: messageInput.value,
            };
            ws.send(JSON.stringify(message));
            messageInput.value = "";
        };
    </script>
</body>
</html>

Этот HTML-файл включает простую форму для ввода имени пользователя и сообщения, а также div для отображения сообщений чата.

Шаг 3: Реализация сервера WebSocket

Теперь давайте реализуем сервер WebSocket, используя библиотеку Gorilla WebSocket. Сначала установите библиотеку:

go get github.com/gorilla/websocket

Вот как можно изменить код Go, чтобы включить функциональность WebSocket:

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

func wshandler(w http.ResponseWriter, r *http.Request) {
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Fatal(err)
    }
    defer ws.Close()

    for {
        var message struct {
            Username string `json:"username"`
            Content  string `json:"content"`
        }
        err := ws.ReadJSON(&message)
        if err != nil {
            log.Println(err)
            break
        }

        // Рассылка сообщения всем подключённым клиентам
        for _, client := range clients {
            if client != ws {
                err := client.WriteJSON(message)
                if err != nil {
                    log.Println(err)
            }
        }}
    }
}

var clients = make(map[*websocket.Conn]bool)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "frontend/index.html")
    })

    http.HandleFunc("/ws", wshandler)

    log.Println("HTTP сервер запущен на :8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }}

Этот код устанавливает конечную точку WebSocket по адресу /ws и обрабатывает входящие сообщения путём их широковещательной рассылки всем подключённым клиентам.

Заключение

Создание чат-бота с помощью Go и WebSockets является интересным и полезным проектом, который позволит вам понять мощь коммуникации в режиме реального времени. С этим руководством вы узнали, как настроить HTTP-сервер, создать простой интерфейс, реализовать сервер WebSocket и управлять несколькими клиентами. Независимо от того, создаёте ли вы простое чат-приложение или более сложную систему реального времени, принципы, изложенные здесь, послужат надёжной основой.