1

我正在尝试构建一个 Twisted/Django mashup,它可以让我通过 Django 的管理界面控制由Twisted 服务器管理的各种客户端连接。意思是,我希望能够登录到 Django 的管理员并查看当前正在使用哪些协议,每个连接特定的任何详细信息(例如,如果服务器通过 IRC 连接到 freenode,它应该列出当前连接到的所有通道),并允许我通过修改或创建数据库记录来断开或连接新客户端。

最好的方法是什么?有很多关于 DjangoTwisted结合起来的帖子,但我还没有找到任何现有技术来完成我所概述的内容。我见过的所有 Twisted 示例都使用硬编码的连接参数,这让我很难想象当数据库中的记录发出信号时我将如何动态运行 reactor.connectTCP(...) 或 lostConnection(...)。

我的策略是创建一个自定义 ClientFactory,它每 N 秒轮询一次 Django/托管数据库以获取任何命令,并根据需要修改/创建/删除连接,在完成时反映数据库中的新状态。

这看起来可行吗?有更好的方法吗?有谁知道任何实现类似功能的现有项目?

4

2 回答 2

1

轮询数据库是蹩脚的,但不幸的是,数据库很少有好的工具(当然也没有数据库可移植工具)来监控变化。所以你的方法可能没问题。

但是,如果您的应用程序在 Django 中,并且您不支持从其他(非 Django)客户端对数据库进行随机更改,并且您的 WSGI 容器是 Twisted,那么您可以通过callFromThread(connectTCP, ...).

于 2012-11-24T01:20:10.177 回答
1

我一直在研究另一种结合 django 和 twisted 的方式。随意尝试一下:https ://github.com/kowalski/featdjango 。

它的工作方式与其他方式略有不同。它启动了一个扭曲的应用程序和 http 站点。对 django 的请求在一个特殊的线程池中处理。它的特别之处在于,这些线程可以在 Deferred 上等待,这使得将同步 django 应用程序代码与异步扭曲代码结合起来变得很容易。

我想出这样的结构的原因是我的应用程序需要从 django 视图中执行大量 http 请求。我可以一次将它们全部委托给扭曲运行并等待它们的“主应用程序线程”,而不是一一执行它们。与您的问题相似的是,我也有一个异步组件,它是一个单例,我从 django 视图访问它。

例如,这就是您启动扭曲组件以及稍后从视图中获取参考的方式。

import threading

from django.conf import settings

_initiate_lock = threading.Lock()

def get_component():
    global _initiate_lock
    if not hasattr(settings, 'YOUR_CLIENT')
        _initiate_lock.acquire()
        try:
            # other thread might have did our job while we
            # were waiting for the lock
            if not hasattr(settings, 'YOUR_CLIENT'):
                client = YourComponent(**whatever)
                threading.current_thread().wait_for_deferred(
                    client.initiate)
                settings.YOUR_CLIENT = client
        finally:
            _initiate_lock.release()
    return settings.YOUR_CLIENT

上面的代码启动了我的客户端并调用了它的启动方法。此方法是异步的并返回一个 Deferred。我在那里做了所有必要的设置。django 线程将等待它完成,然后再处理下一行。

我就是这样做的,因为我只从请求处理程序中访问它。您可能希望在启动时启动您的组件,以调用 ListenTCP|SSL。比您的 django 请求处理程序只需访问客户端上的一些公共方法即可获取有关连接的数据。这些方法甚至可以返回 Deferred,在这种情况下,您应该使用 .wait_for_defer() 来调用它们。

于 2012-12-21T16:05:06.547 回答