我正在创建Mattermost机器人。 Websocket连接在随机时间段(1分钟,8分钟,2小时等)后收到ping超时(PingTimeoutChannel)后,它将停止响应。最重要的服务器是v.5.13,API是v.4。
该机器人通过创建新的Client4连接到Mattermost API。接下来,它以用户身份登录,并在创建具有收到的授权令牌的Websocket客户端之后。它开始在所有频道上监听,并在接收到指向他的消息(@botname)的事件时,它会自动响应(创建model.post)。
我选择使用简单的用户名/密码身份验证进行登录,就像在Mattermost示例bot中一样。但是,我试图将其重写为个人访问令牌身份验证(如here中的),因为我认为它可以解决超时问题。但是,此解决方案不再起作用,在尝试以这种方式登录时会显示“无效或过期的会话错误,请重新登录”。
所以我放弃了这个想法,开始搜索发生超时的地方。服务器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添加到了退出函数并运行了一个竞赛检测器。通过从案例事件中删除一个:= [...],解决了数据争用问题。竞赛检测器不再报告任何问题,但是该僵尸程序仍会在一段时间后停止响应。
我发现第一次PingTimeout发生时,对等方停止响应,直到我重新启动应用程序。 Websocket的重新连接没有帮助。但是,我实际上不知道如何解决该问题,甚至不存在解决方案。