【问题标题】:Controlling a Twisted Server from Django从 Django 控制 Twisted 服务器
【发布时间】:2012-11-23 05:08:55
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: python django twisted twisted.web


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我一直在研究另一种结合 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
      

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

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

      【讨论】:

        猜你喜欢
        • 2013-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-02
        • 1970-01-01
        • 1970-01-01
        • 2011-01-13
        相关资源
        最近更新 更多