Python3 webserver 在 IRC bot 的线程之间进行通信

Posted

技术标签:

【中文标题】Python3 webserver 在 IRC bot 的线程之间进行通信【英文标题】:Python3 webserver communicate between threads for IRC bot 【发布时间】:2016-07-23 13:26:22 【问题描述】:

我已经阅读了很多关于线程、队列、池等的文档,但仍然不知道如何解决我的问题。 情况如下: 我构建了一个由cherrypy 提供服务的python3 Django 应用程序。该应用程序基本上是另一个 IRC 客户端。当我第一次使用 GUI 运行我的代码时,IRC 机器人通过一个守护线程启动并监听事件。我的问题如下:如何将数据发送到该线程(和我的机器人),例如告诉他加入第二个频道?当我第二次运行我的代码时,显然会创建我的机器人的一个新实例,以及一个新的服务器连接。我需要一种通过 GUI 交互与我的机器人进行通信的方法。现在,我必须让我的机器人对特定事物做出反应的唯一方法是读取数据库。其他一些 GUI 操作会更改该数据库。这是一个糟糕的系统。

这是启动我的机器人的相关代码。

def DCC_deamonthread(c, server, nickname, upload):
    try:
        c.connect(server, 6667, nickname)
        c.start()
    except irc.client.ServerConnectionError as x:
        log("error" + str(x)).write()
        upload.status, upload.active = "Error during connection", False
        upload.save()

def upload_file(filename, rec_nick, pw):
    global upload
    Upload_Ongoing.objects.all().delete()
    upload = Upload_Ongoing(filename=filename,status="Connecting to server...", active=True)
    upload.save()
    irc.client.ServerConnection.buffer_class.encoding = 'latin-1'
    c = DCCSend(filename, rec_nick, pw)
    server = "irc.rizon.net"
    nickname = ''.join(random.choice(string.ascii_lowercase) for i in range(10))
    t = threading.Thread(target=DCC_deamonthread, args=(c, server, nickname, upload))
    t.daemon=True
    t.start()

【问题讨论】:

【参考方案1】:

问题在于,正如您所注意到的,每次上传时都会产生一个新线程/机器人。一个可能的解决方案是重写你的代码来做这样的事情:

event_queue = multiprocessing.Queue() # Events that will be sent to the IRC bot thread

def irc_bot_thread():
    bot = connect_to_irc()

    for event in event_queue:
        bot.handle_event(event)

threading.Thread(target=irc_bot_thread).start()

def upload_file(filename, rec_nick, pw):
    # Django stuff

    event_queue.push(<necessary data for use by the bot>)

【讨论】:

event_queue 不会被新的执行覆盖吗? 好吧,肯定会创建一个新的 event_queue。但事实上,通过让我的机器人在循环中读取 event_queue,然后在另一个线程中导入 event_queue,我设法通过 GUI 正确地将数据发送到第一个机器人。这就是我一直在寻找的。还有另一种可能的方法吗? (我将在我设法完全实施该解决方案后立即进行验证)。 另外,有没有一种有效的方法来读取队列项目而不删除项目?是否有另一个类似的对象允许数据持久性? 1.这取决于模块是在每次执行时重新加载(php/CGI 风格)还是保留(WSGI 风格)。我从未尝试过,但在我看来,cherrypy 做第二个更合乎逻辑。 2.另一种可能的方法是必须使用每个自己的 HTTP 服务器(Limnoria 确实有一个)单独运行一个机器人,并让 Django 脚本向机器人发出 HTTP 请求。

以上是关于Python3 webserver 在 IRC bot 的线程之间进行通信的主要内容,如果未能解决你的问题,请参考以下文章

非常基本的 Python IRC 机器人上的“注册超时”

webserver实时查询当天的天气情况

Kivy 1.8.x Python3 对 Ubuntu 的支持

如何在 IRC 服务器中发送消息聊天?

什么是 IRC?

在 IRC 消息中插入换行符