1

我正在创建一个 Mattermost 机器人。在 websocket 连接在随机时间段(1 分钟、8 分钟、2 小时等)后收到 ping 超时 (PingTimeoutChannel) 后,它会停止响应。Mattermost 服务器是 v.5.13,API v.4。

机器人通过创建新的 Client4 连接到 Mattermost API。接下来,它以用户身份登录,并在创建一个接收到授权令牌的 Websocket 客户端之后。它开始监听所有频道,当它收到一个事件,它是一条发给他​​的消息(@botname),它会自动响应(创建 model.post)。

我选择使用简单的用户名/密码身份验证进行登录,就像在 Mattermost 示例机器人中一样。但是,我尝试将其重写为个人访问令牌身份验证(如此),因为我认为它可以解决超时问题。但是,此解决方案不再起作用,它在尝试以这种方式登录时给出“无效或过期的会话错误,请重新登录”。

所以我放弃了这个想法,开始寻找超时发生的地方。服务器 ping 正常,websocket 不正常。我尝试了很多方法,直到我重新连接(通过再次创建新的 Mattermost API 和 Websocket 客户端)。机器人仍然没有响应。我已经没有想法了。

Websocket 连接(跳过错误处理):

    if config.BotCfg.Port == "443" {
        protocol = "https"
        secure = true
    }

        config.ConnectionCfg.Client = model.NewAPIv4Client(fmt.Sprintf("%s://%s:%s", protocol, config.BotCfg.Server, config.BotCfg.Port))


    user,resp := config.ConnectionCfg.Client.Login(config.BotCfg.BotName, config.BotCfg.Password)

    setBotTeam()

    if limit.Users == nil {
        limit.SetUsersList()
    }

    ws := "ws"
    if secure {
        ws = "wss"
    }

    if Websocket != nil {
        Websocket.Close()
    }

    websocket, err := model.NewWebSocketClient4(fmt.Sprintf("%s://%s:%s", ws, config.BotCfg.Server, config.BotCfg.Port), config.ConnectionCfg.Client.AuthToken)

听力功能:

        for {
            select {

            case <-connection.Websocket.PingTimeoutChannel:
                logs.WriteToFile("Websocket ping timeout. Connecting again.")
                log.Println("Websocket ping timeout. Connecting again.")
                mux.Lock()
                connection.Connect()
                mux.Unlock()

            case event := <-connection.Websocket.EventChannel:
                mux.Lock()
                if event != nil {
                    if event.IsValid() && isMessage(event.Event){
                        handleEvent(event)
                    }
                }
                mux.Unlock()
            }
        }
    }()
    // block to the go function
    select {}

我希望机器人能够连续运行。如果您对如何解决此问题有任何建议,我将不胜感激!

编辑:正如Cerise建议的那样,我将 SIGQUIT 添加到退出函数并运行了一个竞赛检测器。通过从案例事件中删除一个 if 来修复数据竞争问题:= [...]。种族检测器不再报告任何问题,但是机器人在一段时间后仍然停止响应。

我发现第一次 PingTimeout 发生时,对等方停止响应,直到我重新启动应用程序。Websocket 的重新连接没有帮助。但是,我实际上不知道如何解决这个问题,或者解决方案是否存在。

4

0 回答 0