Go语言实现一个简单的并发聊天室的项目实战

下面我将为你详细讲解“Go语言实现一个简单的并发聊天室的项目实战”的完整攻略。

1. 确定项目需求

在开始我们的项目之前,需要先明确项目需求。这是任何项目开始之前都必须要做的。在聊天室项目中,我们需要实现以下需求:

  • 支持多个用户同时在线
  • 用户能够发送消息到聊天室中
  • 用户能够接收到来自其他用户的消息
  • 用户能够退出聊天室

2. 设计数据结构

在开始编写代码之前,我们需要设计一下数据结构。在本项目中我们需要用到以下三种数据结构。

User

type User struct {
    ID   int
    Name string
    Conn net.Conn
}

每个用户都有唯一的ID,名字和和他(她)建立连接的网络连接。

Message

type Message struct {
    SenderID   int
    ReceiverID int
    Content    string
}

每个消息都有发送者和接受者的ID和内容。

ChatRoom

type ChatRoom struct {
    Users    []*User
    Messages []*Message
}

聊天室包含所有在线用户和所有已经发送的消息。

3. 编写代码

3.1 初始化聊天室和用户

func main() {
    chatRoom := &ChatRoom{}
    users := make([]*User, 0)
}

3.2 添加用户

func (c *ChatRoom) addUser(user *User) {
    c.Users = append(c.Users, user)
}

3.3 发送消息

func (c *ChatRoom) sendMessage(message *Message) {
    c.Messages = append(c.Messages, message)
}

3.4 广播消息

func (c *ChatRoom) broadcastMessage(message *Message) {
    for _, user := range c.Users {
        if user.ID != message.SenderID {
            fmt.Fprintf(user.Conn, "[%s]: %s\n", user.Name, message.Content)
        }
    }
}

3.5 客户端处理

func handleConn(conn net.Conn, chatRoom *ChatRoom) {
    user := &User{
        ID:   rand.Int(),
        Name: "user",
        Conn: conn,
    }
    chatRoom.addUser(user)
    fmt.Fprintf(conn, "Welcome to the chat room, your ID is %d\n", user.ID)

    scanner := bufio.NewScanner(conn)
    for scanner.Scan() {
        msg := scanner.Text()
        if msg == "quit" {
            fmt.Fprintf(conn, "Goodbye!\n")
            conn.Close()
            break
        }
        message := &Message{
            SenderID:   user.ID,
            ReceiverID: 0,
            Content:    msg,
        }
        chatRoom.sendMessage(message)

        go chatRoom.broadcastMessage(message)
    }
}

3.6 启动服务

func main() {
    chatRoom := &ChatRoom{}
    users := make([]*User, 0)

    ln, err := net.Listen("tcp", ":8888")
    if err != nil {
        log.Fatal(err)
    }
    defer ln.Close()

    for {
        conn, err := ln.Accept()
        if err != nil {
            log.Fatal(err)
        }

        go handleConn(conn, chatRoom)
    }
}

4. 示例说明

示例1:启动服务器

在终端中运行以下命令启动服务器:

$ go run main.go

示例2:启动客户端

在终端中运行以下命令启动客户端:

$ telnet localhost 8888

示例3:用户发送消息

用户可以使用telnet向聊天室发送消息:

$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome to the chat room, your ID is 999
Hello!

示例4:用户在聊天室中广播消息

所有在线用户都能接收到其他用户的消息:

$ go run main.go
[user1]: Hello
[user2]: How are you?

以上就是“Go语言实现一个简单的并发聊天室的项目实战”的完整攻略,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Go语言实现一个简单的并发聊天室的项目实战 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Java多线程并发生产者消费者设计模式实例解析

    Java多线程并发生产者消费者设计模式是一种常见的并发编程模式,它可以让生产者不停地生产数据,消费者不停地消费数据,从而实现高效的数据处理。下面,我将分为以下几个步骤详细讲解Java多线程并发生产者消费者设计模式实例解析。 1.生产者消费者设计模式的原理 生产者消费者设计模式是一种基于阻塞队列的并发模式。它的基本思想是,将生产者线程和消费者线程分别放在不同的…

    多线程 2023年5月17日
    00
  • 使用lua+redis解决发多张券的并发问题

    下面我详细讲解一下使用Lua+Redis解决发多张券的并发问题的攻略。 什么是发多张券的并发问题 发多张券的并发问题是指当多个用户同时请求获取优惠券时,可能会造成出现超卖的情况,即券码数量不足,统一券码被领取数超过了预设数量。这种问题在高并发场景下尤为常见。 解决方案 一种常见的解决方案是使用分布式锁,但是这种方案不够优雅,因为它需要多次请求获取锁,而且需要…

    多线程 2023年5月16日
    00
  • Golang WorkerPool线程池并发模式示例详解

    Golang WorkerPool线程池并发模式示例详解 简介 WorkerPool即工作池,也称为线程池。它是一种并发编程模式,通常用于解决并发问题。在WorkerPool中,创建固定数量的worker,他们并行地从池中获取任务,并在处理任务时将其标记为完成。当所有可用的Worker都在使用时,新任务将被放入队列中,并等待有空闲的Worker。 原理 Wo…

    多线程 2023年5月17日
    00
  • java基本教程之java线程等待与java唤醒线程 java多线程教程

    Java线程等待与唤醒线程 线程等待 线程等待就是让线程先暂停一下,等待特定的条件被满足时再继续执行,一般情况下会使用wait()方法进行线程等待。 wait()方法的用法: synchronized(monitorObject) { while(!conditionWarranted()) { monitorObject.wait(); } 代码中的mon…

    多线程 2023年5月16日
    00
  • 一文搞懂Java并发AQS的共享锁模式

    一文搞懂Java并发AQS的共享锁模式 什么是AQS AQS全称为AbstractQueuedSynchronizer(抽象队列式同步器),是Java并发包中的一种基础组件,用于实现锁和同步器工具类。在Java中,锁和同步器的实现往往都依赖于AQS。 AQS实现了一个双向队列,队列里面的元素是“线程节点”,每一个线程节点都可以对应一个线程。线程节点可以用来保…

    多线程 2023年5月16日
    00
  • Linux 多线程编程实例

    针对“Linux 多线程编程实例”的完整攻略,我为你提供以下内容: Linux 多线程编程的基础知识 进程与线程的概念 进程是资源分配的最小单位,线程是 CPU 调度的最小单位。 线程的优缺点 线程的优点在于线程的创建、销毁、上下文切换等开销相对较小,可以充分利用 CPU 资源,提高程序的并发性能,而缺点在于线程之间共享内存时需要进行同步和协调,比较容易出现…

    多线程 2023年5月17日
    00
  • Java httpClient连接池支持多线程高并发的实现

    Java httpClient是一种开源的基于Http的请求和响应类型,它可以通过连接池技术适用于高并发的请求场景,下面是httpClient连接池支持多线程高并发的实现攻略: 1. 引入依赖 <dependency> <groupId>org.apache.httpcomponents</groupId> <art…

    多线程 2023年5月16日
    00
  • C++ 多线程编程建议之 C++ 对多线程/并发的支持(下)

    下面是关于“C++ 多线程编程建议之 C++ 对多线程/并发的支持(下)”的完整攻略。 什么是 C++ 对多线程/并发的支持 C++11 引入了对多线程/并发的支持,使得 C++ 语言能够更好地应对多线程程序的开发和实现。这些支持主要包括以下内容: std::thread 类型:C++11 引入了 std::thread 类型,它代表了一个执行线程,可以运行…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部