Go language server programming practice: building a simple web chat room

WBOY
Release: 2023-06-18 08:27:17
Original
1749 people have browsed it

Go language is used more and more widely in the field of server programming. Its fast, efficient and concurrency features have become the reasons why many people choose it. This article will introduce you to how to build a simple Web chat room in Go language, including real-time message transmission, multi-user online interaction and other related knowledge points.

1. Go language Web framework selection

In the Go language, there are many web frameworks to choose from, among which the more popular ones are Beego, Gin, Echo, etc. This article chooses to use the Echo framework because it is lightweight, high-performance, and easy to use, and is suitable for quickly building Web applications. Before using the Echo framework, please open a terminal and execute the following command to obtain the dependency package:

go get -u github.com/labstack/echo
Copy after login

2. Functional design

Before building this web chat room, we need to design its required functions Modules and processes:

  1. Register and log in to the account to achieve user authentication.
  2. The home page of the chat room can display the list of online users, historical chat records, etc.
  3. Real-time message transmission, supporting multi-user online interaction.
  4. When the browser is closed, the WebSocket connection to the server is disconnected and the user is marked offline.

3. Implementation steps

Below we will implement the above functional modules and processes step by step:

  1. Register and log in account:

In the Go language, you can use the third-party package bcrypt to implement password encryption. We need to create the user structure User first, and then use the gorm library to create the database table.

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

The processing function code for user registration and login is as follows:

// 用户注册
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",
    })
}
Copy after login
  1. Chat room homepage:

In the chat room homepage, online users need to be displayed List and chat history. The online user list can be saved in a Map, where the key is the user name and the value is information related to the WebSocket connection, such as connection ID, connection time, etc.

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

Historical chat records can be stored using arrays or Redis-like data structures. The following is the code of the home page processing function:

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

Among them, room.html is the template file, clients and msgs are the online user list and historical chat records respectively.

  1. Real-time message transmission:

In the Echo framework, real-time message transmission can be achieved very simply using WebSockets. We need to define a WebSocket processing function. After the client successfully connects to the server, its information will be added to the online user list; when the client sends a message, the message will be sent to all connected clients.

// 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
}
Copy after login
  1. When closing a WebSocket connection, disconnect from the server and mark the user offline. We can use the defer statement in the WebSocket processing function to delete the user information in the online user list at the end of the function.
defer func() {
    delete(clients, client.Username)
}()
Copy after login

4. Summary

This article implements a simple Web chat room by using the Echo framework and WebSockets, including user authentication, online user list, historical chat records, and real-time messages transmission and other functions. At the same time, we also use the gorm library and bcrypt package to implement user management and password encryption functions.

In practice, we also need to consider security issues such as message filtering and sensitive word filtering. I hope readers can learn through this article how to use Go language to build web applications, as well as commonly used libraries and frameworks.

The above is the detailed content of Go language server programming practice: building a simple web chat room. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!