gpt4 book ai didi

Python 3 (Bot) 脚本停止工作

转载 作者:太空宇宙 更新时间:2023-11-04 05:58:24 25 4
gpt4 key购买 nike

我正在尝试使用 QueryServer 连接到 TeamSpeak 服务器来制作机器人。我听取了 this thread 的建议,但是我仍然需要帮助。

这是 The TeamSpeak API我正在使用的。

在编辑之前,这是我脚本中实际发生的事情的摘要(1 个连接):

  1. 它连接。
  2. 它检查 channel ID(以及它自己的客户端 ID)
  3. 加入 channel 并开始阅读所有内容
  4. 如果有人说出特定命令,它会执行该命令,然后断开连接。

我怎样才能让它不断开连接?如何让脚本保持“等待”状态,以便在命令执行后继续读取?

我正在使用 Python 3.4.1
我尝试学习线程,但要么我很笨,要么它不像我想象的那样工作。还有另一个“错误”,一旦等待事件,如果我没有用命令触发任何东西,它会在 60 秒后断开连接。

#Librerias
import ts3
import threading
import datetime
from random import choice, sample

# Data needed #
USER = "thisisafakename"
PASS = "something"
HOST = "111.111.111.111"
PORT = 10011
SID = 1


class BotPrincipal:
def __init__(self, manejador=False):
self.ts3conn = ts3.query.TS3Connection(HOST, PORT)
self.ts3conn.login(client_login_name=USER, client_login_password=PASS)
self.ts3conn.use(sid=SID)
channelToJoin = Bot.GettingChannelID("TestingBot")
try: #Login with a client that is ok
self.ts3conn.clientupdate(client_nickname="The Reader Bot")
self.MyData = self.GettingMyData()
self.MoveUserToChannel(ChannelToJoin, Bot.MyData["client_id"])
self.suscribirEvento("textchannel", ChannelToJoin)
self.ts3conn.on_event = self.manejadorDeEventos
self.ts3conn.recv_in_thread()
except ts3.query.TS3QueryError: #Name already exists, 2nd client connect with this info
self.ts3conn.clientupdate(client_nickname="The Writer Bot")
self.MyData = self.GettingMyData()
self.MoveUserToChannel(ChannelToJoin, Bot.MyData["client_id"])

def __del__(self):
self.ts3conn.close()

def GettingMyData(self):
respuesta = self.ts3conn.whoami()
return respuesta.parsed[0]

def GettingChannelID(self, nombre):
respuesta = self.ts3conn.channelfind(pattern=ts3.escape.TS3Escape.unescape(nombre))
return respuesta.parsed[0]["cid"]

def MoveUserToChannel(self, idCanal, idUsuario, passCanal=None):
self.ts3conn.clientmove(cid=idCanal, clid=idUsuario, cpw=passCanal)

def suscribirEvento(self, tipoEvento, idCanal):
self.ts3conn.servernotifyregister(event=tipoEvento, id_=idCanal)

def SendTextToChannel(self, idCanal, mensajito="Error"):
self.ts3conn.sendtextmessage(targetmode=2, target=idCanal, msg=mensajito) #This works
print("test") #PROBLEM HERE This doesn't work. Why? the line above did work

def manejadorDeEventos(sender, event):
message = event.parsed[0]['msg']
if "test" in message: #This works
Bot.SendTextToChannel(ChannelToJoin, "This is a test") #This works


if __name__ == "__main__":
Bot = BotPrincipal()
threadprincipal = threading.Thread(target=Bot.__init__)
threadprincipal.start()

在使用 2 个机器人之前,我测试了在 SendTextToChannel 连接时启动它,它运行良好,允许我在将文本发送到 channel 后做任何我想做的事情。导致整个 python 代码停止的错误只有在由 manejadorDeEventos 触发时才会发生

编辑 1 - 线程试验。
我用线程搞砸了很多时间,得到了 2 个客户端同时连接的结果。不知何故,我认为其中一个正在阅读事件,另一个正在回答。该脚本不再自行关闭,这是一个胜利,但拥有克隆连接看起来不太好。

编辑 2 - 更新代码和问题的实际状态。
我设法使双连接或多或少“正常”工作,但如果房间内 60 秒没有任何反应,它就会断开连接。尝试使用 Threading.timer 但我无法使其工作。已为其更新了整个问题代码。

我想要一个答案,它可以帮助我从 channel 中读取和回答它,而不需要为它连接第二个机器人(就像它实际上正在做的......)如果答案我会加分还帮助我理解了一种每 50 秒向服务器查询一次的简单方法,这样它就不会断开连接。

最佳答案

从看the source , recv_in_thread 不会创建一个循环接收消息直到退出时间的线程,它会创建一个接收单个消息然后退出的线程:

def recv_in_thread(self):
"""
Calls :meth:`recv` in a thread. This is useful,
if you used ``servernotifyregister`` and you expect to receive events.
"""
thread = threading.Thread(target=self.recv, args=(True,))
thread.start()
return None

这意味着你必须重复调用recv_in_thread,而不是只调用一次。

通过阅读文档,我不确定在哪里这样做,但大概是在接收到的事件触发的任何回调结束时;我认为这是您的 manejadorDeEventos 方法? (或者它可能与 servernotifyregister 方法有关?我不确定 servernotifyregister 是做什么用的,on_event 是做什么用的……)


manejadorDeEventos 提出了两个方面:

  • 您已声明 manejadorDeEventos 错误。每个方法都必须将 self 作为其第一个参数。当您传递绑定(bind)方法时,例如 self.manejadorDeEventos,绑定(bind)的 self 对象将作为第一个参数传递,在调用者传递的任何参数之前。 (对于 classmethodstaticmethod 有异常(exception),但这些不适用于此处。)此外,在该方法中,您几乎肯定会访问 self,不是一个全局变量 Bot,恰好与 self 是同一个对象。
  • 如果 manejadorDeEventos 实际上是 recv_in_thread 的回调,那么这里就会出现竞争条件:如果第一条消息在主线程完成 之前到达on_event 分配,recv_on_thread 将无法调用您的事件处理程序。 (这正是那种经常出现一百万次的错误,当您在部署或发布代码几个月后发现它时,调试起来会非常痛苦。)因此,将这两行颠倒过来。

最后一件事:简要浏览一下这个库的代码有点令人担忧。它看起来不像是真正知道自己在做什么的人写的。我上面复制的方法只有3行代码,但它包括一个无用的return None和一个永远无法join的泄漏的Thread ,更不用说让您在收到每个事件后调用此方法(并产生一个新线程)的整个设计很奇怪,而且更是如此,因为它没有真正解释。如果这是您必须使用的服务的标准客户端库,那么您真的没有太多选择,但如果不是,我会考虑寻找其他库。

关于Python 3 (Bot) 脚本停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26490533/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com