首頁 >後端開發 >Golang >Go語言伺服器程式設計實戰:建構簡單的Web聊天室

Go語言伺服器程式設計實戰:建構簡單的Web聊天室

WBOY
WBOY原創
2023-06-18 08:27:171810瀏覽

Go語言在伺服器程式設計領域的應用越來越廣泛,其快速、高效以及並發特性成為了許多人選擇它的原因。本篇文章將為大家介紹如何在Go語言中建立一個簡單的Web聊天室,包含即時訊息、多用戶線上互動等相關知識點。

一、Go語言Web框架選擇

在Go語言中,有許多Web框架可以選擇,其中比較流行的有Beego、Gin、Echo等。本文選擇使用Echo框架,因為它具有輕量級、高效能、易用等特點,適合快速建立Web應用程式。在使用Echo框架之前,請打開終端機並執行以下命令獲取依賴套件:

go get -u github.com/labstack/echo

二、功能設計

在建立這個Web聊天室之前,我們需要設計其所需的功能模組和流程:

  1. 註冊和登入帳號,實現使用者認證。
  2. 聊天室首頁,能夠顯示線上使用者清單、歷史聊天記錄等。
  3. 即時訊息傳輸,支援多用戶線上互動。
  4. 關閉瀏覽器時,斷開與伺服器的WebSocket連接,並將使用者標記為離線狀態。

三、實作步驟

下面我們將一步一步實現上述的功能模組和流程:

  1. 註冊和登入帳號:

在Go語言中,可以使用第三方套件bcrypt來實現密碼加密。我們需要先建立使用者結構體User,之後再使用gorm庫建立資料庫表。

type User struct {
    gorm.Model
    Username string `gorm:"unique;not null"`
    Password string `gorm:"not null"`
}

用戶註冊和登入的處理函數程式碼如下:

// 用户注册
func Register(c echo.Context) error {
    username := c.FormValue("username")
    password := c.FormValue("password")
    confirmPwd := c.FormValue("confirm_pwd")
    u := &models.User{
        Username: username,
        Password: util.HashPwd(password),
    }
    if password != confirmPwd {
        return c.JSON(http.StatusOK, map[string]interface{}{
            "success": false,
            "message": "Passwords do not match",
        })
    }
    err := db.Create(&u).Error
    if err != nil {
        return c.JSON(http.StatusOK, map[string]interface{}{
            "success": false,
            "message": "Username already exists",
        })
    }
    return c.JSON(http.StatusOK, map[string]interface{}{
        "success": true,
        "message": "Register success",
    })
}

// 用户登录
func Login(c echo.Context) error {
    username := c.FormValue("username")
    password := c.FormValue("password")
    user := &models.User{}
    err := db.Where("username = ?", username).First(&user).Error
    if err != nil {
        return c.JSON(http.StatusOK, map[string]interface{}{
            "success": false,
            "message": "Username or password is incorrect",
        })
    }
    if util.CheckPwd(password, user.Password) {
        return c.JSON(http.StatusOK, map[string]interface{}{
            "success": true,
            "message": "Login success",
        })
    }
    return c.JSON(http.StatusOK, map[string]interface{}{
        "success": false,
        "message": "Username or password is incorrect",
    })
}
  1. 聊天室首頁:

在聊天室首頁中,需要顯示線上用戶列表和歷史聊天記錄。線上用戶清單可以保存在Map中,其中鍵為用戶名,值為與WebSocket連接相關的信息,如連接ID、連接時間等。

// 在线用户列表
var clients = make(map[string]*Client)

歷史聊天記錄可以使用陣列或類似Redis的資料結構來儲存。以下是首頁處理函數的程式碼:

// 聊天室首页
func Room(c echo.Context) error {
    return c.Render(http.StatusOK, "room.html", map[string]interface{}{
        "clients": clients,
        "msgs":    msgs,
    })
}

其中,room.html為範本文件,clients和msgs分別是線上使用者清單和歷史聊天記錄。

  1. 即時訊息傳輸:

在Echo框架中,使用WebSockets可以非常簡單地實現即時訊息傳輸。我們需要定義一個WebSocket處理函數,客戶端與伺服器連線成功後,將其資訊新增至線上使用者清單;當客戶端傳送訊息時,將訊息傳送給所有連線的客戶端。

// WebSocket处理函数
func wsHandler(c echo.Context) error {
    // 建立WebSocket连接
    ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
    if err != nil {
        return err
    }
    defer ws.Close()

    // 获取用户名
    username, ok := c.QueryParams()["username"]
    if !ok {
        return errors.New("username is required")
    }

    // 添加用户
    client := &Client{
        WS:        ws,
        Username: username[0],
        ConnTime:  time.Now(),
    }
    clients[client.Username] = client

    // 遍历用户列表,发送欢迎消息
    for _, c := range clients {
        msg := &Message{
            Type: WelcomeMsg,
            Data: fmt.Sprintf("User '%s' joined the chat room", client.Username),
        }
        err = c.Send(msg)
        if err != nil {
            log.Println(err)
            continue
        }
    }

    // 接收消息,广播给所有用户
    for {
        msg := &Message{}
        err = client.Receive(msg)
        if err != nil {
            if err == io.EOF {
                delete(clients, client.Username)
                for _, c := range clients {
                    msg = &Message{
                        Type: LeaveMsg,
                        Data: fmt.Sprintf("User '%s' left the chat room", client.Username),
                    }
                    err = c.Send(msg)
                    if err != nil {
                        log.Println(err)
                        continue
                    }
                }
                break
            }
            log.Println(err)
            continue
        }
        for _, c := range clients {
            if c.Username == client.Username {
                continue
            }
            err = c.Send(msg)
            if err != nil {
                log.Println(err)
                continue
            }
        }
        msgs = append(msgs, *msg)
    }

    return nil
}
  1. 關閉WebSocket連線時,中斷與伺服器的連線並將使用者標記為離線狀態。我們可以在WebSocket處理函數中使用defer語句,在函數結束時刪除線上使用者清單中的使用者資訊。
defer func() {
    delete(clients, client.Username)
}()

四、總結

本文透過使用Echo框架和WebSockets,實現了一個簡單的Web聊天室,包括使用者認證、線上使用者清單、歷史聊天記錄、即時訊息傳輸等功能。同時,我們也使用了gorm庫和bcrypt包,來實現用戶管理和密碼加密功能。

在實踐中,我們還需要考慮諸如訊息過濾、敏感詞過濾等安全性問題。希望讀者們能夠透過本文了解如何使用Go語言建立Web應用程序,以及常用的函式庫和框架。

以上是Go語言伺服器程式設計實戰:建構簡單的Web聊天室的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn