簡體   English   中英

從 Django 控制 Twisted 服務器

[英]Controlling a Twisted Server from Django

我正在嘗試構建一個 Twisted/Django mashup,它可以讓我通過 Django 的管理界面控制由Twisted 服務器管理的各種客戶端連接。 意思是,我希望能夠登錄到 Django 的管理員並查看當前正在使用的協議,每個連接特定的任何詳細信息(例如,如果服務器通過 IRC 連接到 freenode,它應該列出當前連接的所有通道),並允許我通過修改或創建數據庫記錄來斷開或連接新客戶端。

什么是最好的方法來做到這一點? 有很多關於DjangoTwisted 結合的帖子,但我還沒有找到任何可以完成我所概述的工作的現有技術。 我見過的所有 Twisted 示例都使用硬編碼的連接參數,這讓我很難想象當數據庫中的記錄發出信號時,我將如何動態運行 reactor.connectTCP(...) 或 lossConnection(...)。

我的策略是創建一個自定義 ClientFactory,它每 N 秒輪詢一次 Django/托管數據庫的任何命令,並根據需要修改/創建/刪除連接,在完成時反映數據庫中的新狀態。

這看起來可行嗎? 有沒有更好的方法? 有誰知道任何實現類似功能的現有項目?

輪詢數據庫是蹩腳的,但不幸的是,數據庫很少有用於監視更改的好工具(當然也沒有數據庫可移植工具)。 所以你的方法可能沒問題。

但是,如果您的應用程序在 Django 中並且您不支持從其他(非 Django)客戶端對數據庫進行隨機更改,並且您的 WSGI 容器是 Twisted,那么您可以通過執行callFromThread(connectTCP, ...) .

我一直在研究另一種結合 django 和扭曲的方法。 隨意嘗試一下: 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

上面的代碼啟動我的客戶端並調用其上的啟動方法。 此方法是異步的,並返回一個延遲。 我在那里做了所有必要的設置。 django 線程將等待它完成,然后再處理到下一行。

我就是這樣做的,因為我只從請求處理程序訪問它。 您可能希望在啟動時啟動您的組件,以調用 ListenTCP|SSL。 比您的 django 請求處理程序可以獲取有關連接的數據,只需訪問您客戶端上的一些公共方法。 這些方法甚至可能返回 Deferred,在這種情況下,您應該使用 .wait_for_defer() 來調用它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM