如何保持Python 3脚本(机器人)运行
(英语不是母语,可能表达得不太好。 我也是编程新手)。
你好,我正在尝试通过QueryServer连接到一个TeamSpeak服务器,以制作一个机器人。经过几天的努力……它终于可以工作了,但还有一个问题让我卡住了。
如果你需要查看,我正在使用的TeamSpeak API是: http://py-ts3.readthedocs.org/en/latest/api/query.html
以下是我的脚本实际发生的事情的总结:
- 它成功连接。
- 它检查频道ID(还有它自己的客户端ID)
- 它加入了频道
- 脚本结束,所以它断开了连接。
我的问题是:我该如何让它不断开连接?我该如何让脚本保持在“等待”状态,以便可以读取如果有人在频道里输入“hi bot”?所有读取文本和回复的代码似乎都很简单,但我遇到的问题是,无法让机器人“运行”,因为脚本运行结束后文件就关闭了。
更多信息:
我使用的是Python 3.4.1。
我尝试学习线程 http://www.tutorialspoint.com/python/python_multithreading.htm,但要么是我笨,要么它的工作方式和我想的不一样。
在API中,有一个名为 on_event
的函数,我希望它能一直运行。机器人的代码应该只运行一次,然后保持“等待”,直到发生事件。我该怎么做?完全没有头绪。
代码:
import ts3
import telnetlib
import time
class BotPrincipal:
def Conectar(ts3conn):
MiID = [i["client_id"] for i in ts3conn.whoami()]
ChannelToJoin = "[Pruebas] Bots"
ts3conn.on_event = BotPrincipal.EventHappened()
try:
BuscandoIDCanal = ts3conn.channelfind(pattern=ChannelToJoin)
IDCanal = [i["cid"] for i in BuscandoIDCanal]
if not IDCanal:
print("No channel found with that name")
return None
else:
MiID = str(MiID).replace("'", "")
MiID = str(MiID).replace("]", "")
MiID = str(MiID).replace("[", "")
IDCanal = str(IDCanal).replace("'", "")
IDCanal = str(IDCanal).replace("]", "")
IDCanal = str(IDCanal).replace("[", "")
print("ID de canal " + ChannelToJoin + ": " + IDCanal)
print("ID de cliente " + Nickname + ": " + MiID)
try:
print("Moving you into: " + ChannelToJoin)
ts3conn.clientmove(cid=IDCanal, clid=MiID) #entra al canal
try:
print("Asking for notifications from: " + ChannelToJoin)
ts3conn.servernotifyregister(event="channel", id_=IDCanal)
ts3conn.servernotifyregister(event="textchannel", id_=IDCanal)
except ts3.query.TS3QueryError:
print("You have no permission to use the telnet command: servernotifyregister")
print("------- Bot Listo -------")
except ts3.query.TS3QueryError:
print("You have no permission to use the telnet command: clientmove")
except ts3.query.TS3QueryError:
print("Error finding ID for " + ChannelToJoin + ". telnet: channelfind")
def EventHappened():
print("Doesn't work")
# Data needed #
USER = "thisisafakename"
PASS = "something"
HOST = "111.111.111.111"
PORT = 10011
SID = 1
if __name__ == "__main__":
with ts3.query.TS3Connection(HOST, PORT) as ts3conn:
ts3conn.login(client_login_name=USER, client_login_password=PASS)
ts3conn.use(sid=SID)
print("Connected to "+HOST)
BotPrincipal.Conectar(ts3conn)
1 个回答
从这个API的简单浏览来看,你需要明确告诉ts3conn
对象去等待事件。似乎有几种方法可以做到这一点,但ts3conn.recv(True)
看起来是最直接的选择:
这个方法会一直阻塞,直到所有未获取的响应都被接收,或者如果
recv_forever
为真,就会一直等待。
可以推测,每当有命令到达时,它会调用你的on_event
处理器,然后当你从这个处理器返回时,它会继续等待下一个命令。
我不确定你是否需要使用线程,但recv_in_thread
的文档让人感觉可能需要:
这个方法会在一个线程中调用
recv()
。如果你使用了servernotifyregister
并且期望接收事件,这个方法会很有用。
你可能想同时接收servernotify事件和命令,而我猜这个库的写法是需要线程来实现的?如果是这样的话,就用ts3conn.recv_in_thread()
代替ts3conn.recv(True)
。如果你查看源代码,你会发现它只是启动了一个后台线程,并在那个线程中调用self.recv(True)
。