有趣生活

当前位置:首页>科技>go ai编程七爪源码用Go

go ai编程七爪源码用Go

发布时间:2026-07-23阅读(1)

导读端到端的实现我们大多数人都喜欢知识竞赛,对吧?有许多应用程序可以通过让我们回答来自不同职业的问题来解渴。在这篇文章中,我将解释我是如何使用Golang实现一....

端到端的实现

我们大多数人都喜欢知识竞赛,对吧? 有许多应用程序可以通过让我们回答来自不同职业的问题来解渴。

在这篇文章中,我将解释我是如何使用 Golang 实现一个实时竞赛应用程序的。

申请流程

需要遵循一些业务规则。

  • 当连接用户达到两个时,比赛将在 3 秒内自动开始。
  • 我们的比赛共有三个州。这些是 NOT_STARTED、STARTED、FINISHED。
  • 问题有四个选项,用户必须在 10 秒内回答一个问题。
  • 比赛结束后,向用户展示排行榜以查看比赛结果。

我的架构决策

在本节中,我将尝试解释为什么我做出了一些决定,并在开始之前尝试对我们的项目提出一些观点。这部分就像电影剧透一样。

  • Websocket 是实现实时应用程序的基本协议。它提供客户端和服务器之间的双向通信。有很多技术文章介绍了它的概念,我就不赘述了。我用它来发送问题并获得连接用户的答案。
  • 我为每个连接的用户使用了一个唯一的 id(如 Session-id)。这样做,我可以轻松区分用户。在我们的例子中,我们用他们的会话 ID 存储我们的用户,我们的服务器使用它们来管理读写操作。
  • 为了支持并发读写操作,我使用了 sync.Map 。我使用 sessionID 作为键,使用 Client 结构作为如下所示的值。客户端结构由两个字段组成,一个用于写入和读取的客户端 WebSocket 连接以及用于计算排行榜的 totalScore。

  • 广播是一个特殊术语,表示同时将消息传输给所有接收者的方法。 不幸的是,gorilla/websocket 中没有广播方法; 因此,我们将使用我们自定义的广播方法向所有用户发送消息。

  • 要将问题发送给我们的用户,我们需要定义一个模型。 在我们的应用程序中,我不想使用 Question 结构,因为它具有 correct_answer 字段。 我想对连接的用户隐藏这些信息,所以我创建了另一个名为 QuestionDTO 的模型,如下所示。

比赛流程

我曾经使用 RunCompetition() 方法管理比赛流程,如下所示。

我通过创建一个 goroutine 在应用程序的主要流程中调用了这个函数。

func RunCompetition() {CompetitionState = CompetitionNotStartedStatefor {if CompetitionState == CompetitionNotStartedState {time.Sleep(CompetitionStateDuration)numberOfClients := CountClient()msg := DetermineCompetitionState(numberOfClients)BroadcastMessage([]byte(msg))if numberOfClients == 2 {time.Sleep(CompetitionStartDuration)CompetitionState = CompetitionStartedState}} else if CompetitionState == CompetitionStartedState {PrepaRequestions()StartSendingQuestions()CompetitionState = CompetitionFinish} else if CompetitionState == CompetitionFinish {leaderBoard := CreateLeaderBoard()jsonBytes, _ := json.Marshal(leaderBoard)BroadcastMessage(jsonBytes)BroadcastMessage([]byte(CompetitionFinishedStateMessage))break}}}

RunCompetition() 方法中有三个 CompetitionState。

  • CompetitionNotStartedState:要开始比赛,必须有两个用户。 当 numberOfClients 等于 2 时,状态变为 CompetitionStartedState。
  • CompetitionStartedState:在这种状态下,我们每 10 秒向所有连接的用户发送问题。

func StartSendingQuestions() {for i := range Questions {Questions[i].IsTimeout = falsequestionDTO := Questions[i].ToDTO()questionDTOBytes, _ := json.Marshal(questionDTO)BroadcastMessage(questionDTOBytes)time.Sleep(QuestionResponseIntervalDuration)Questions[i].IsTimeout = true}}

发送问题时,我们将 Question 结构体转换为 questionDTO 以向连接的用户隐藏正确答案以防止作弊。

10 秒后,我们将 IsTimeout 更改为 true,因为给问题的时间到了。

  • CompetitionFinish:发送完所有问题后, CompetitionState 变为 CompetitionFinish。 比赛结束后,我们必须创建排行榜并将其发送给所有连接的用户。

处理客户端应答流

我们需要从用户那里得到答案来检查和计算他们的分数。

func HandleClientAnswer(sessionID string, message []byte) {var ClientMsg ClientMessagejson.Unmarshal(message, &ClientMsg)for _, question := range Questions {if question.ID == ClientMsg.QuestionId {if question.IsTimeout == true {fmt.Println("Response Time is out")} else {load, _ := Clients.Load(sessionID)client := load.(Client)if ClientMsg.Answer == question.CorrectAnswer {client.totalScore = ScoreForCorrectAnswerClients.Store(sessionID, client)fmt.Printf("Right Answer!!! SessionId: %s, TotalScore: %d\n", sessionID, client.totalScore)} else {fmt.Printf("Wrong Answer!! Your Answer is : %s, Right Answer is : %s, SessionId: %s, TotalScore: %d\n", ClientMsg.Answer, question.CorrectAnswer, sessionID, client.totalScore)}}}}}

用户在指定的时间间隔内正确回答问题可以获得分数( 10)。

这里有一些重要的点:

  • IsTimeout:指定时间间隔
  • 比较 question.ID 和 ClientMsg.QuestionId :判断是否被问到问题
  • 比较 ClientMsg.Answer 和 question.CorrectAnswer :判断用户是否给出了正确答案。

满足这些条件后,用户的分数通过 sessionID 存储在地图上。 我们在 ws() 方法中调用这个函数。

func ws(c echo.Context) error {numberOfClients := CountClient()if numberOfClients >= 2 {return c.string(http.StatusBadRequest, "")}wsConn, err := Upgrader.Upgrade(c.Response(), c.Request(), nil)if err != nil {return err}defer wsConn.Close()sessionID := IDGenerator()Clients.Store(sessionID, Client{wsConn: wsConn,totalScore: 0,})for {_, message, err := wsConn.ReadMessage()if err != nil {Clients.Delete(sessionID)c.Logger().Errorf("Client disconnect msg=%s err=%s", string(message), err.Error())return nil}HandleClientAnswer(sessionID, message)}}

为了让我们的应用程序简单,比赛将从两个用户开始。 如果用户的数量大于 2,我们的应用会发送 http.StatusBadRequest 给用户。

关注七爪网,获取更多APP/小程序/网站源码资源!

TAGS标签:  编程  七爪  源码  Gogo  go ai编程七爪源  码用Go

Copyright © 2024 有趣生活 All Rights Reserve吉ICP备19000289号-5 TXT地图HTML地图XML地图