【问题标题】:Run Non-Twisted-based Python script daemonized with twistd运行使用 twistd 守护的非基于 Twisted 的 Python 脚本
【发布时间】:2011-09-09 12:37:59
【问题描述】:

我正在编写一个由服务器(使用 Twisted)和客户端(不使用 Twisted)组成的 Python 程序

服务器部分使用 Twisted 和 Twisted 的 application framework 实现,并使用 Twistd 启动以被守护。

在不同服务器上运行的客户端是一个简单的 Python 脚本,没有任何 Twisted 内容(也没有特定于应用程序框架的内容)。它也应该作为守护进程运行。仅供参考,这是来源:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import sys
import time
import syslog

SERVER_IP = '127.0.0.1' 
SERVER_PORT = 43278 
BEAT_PERIOD = 1

class HeartbeatClient:
    '''
    A Client sending heartbeats to a monitoring server.
    '''
    def __init__(self, server_ip, port, beat_period):
        syslog.syslog( ('Sending heartbeat to IP %s , port %d' +
                        '\n press Ctrl-C to stop\n') 
                        % (SERVER_IP, SERVER_PORT))

    def run(self):
        while True:
            hbSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            hbSocket.sendto('PyHB', (SERVER_IP, SERVER_PORT))
            if __debug__: 
                print 'Time: %s' % time.ctime()
            time.sleep(BEAT_PERIOD)

if __name__ == '__main__':
    hbc = HeartbeatClient() 
    hbc.run()

现在我想知道我是否也可以使用 Twistd 来守护客户端?因此,我会从客户端创建一个 Twisted-Application。但是我看到的所有关于 Twisted 应用程序的例子都实现了一些 Twisted 互联网服务器的东西(比如在我的例子中是 internet.UDPServer...),我的客户不使用这些东西。

那么,是否可以使用 Twistd 将我的客户端作为守护程序启动,我必须进行哪些更改?我应该重写客户端以充分利用 Twisted 吗?如果是的话,是否有任何类似的示例如何编写基于 Twisted 的网络客户端?

或者我必须为客户端使用不同的守护程序库吗?有一个good library for that,但我试图保持一致并为客户端和服务器使用相同的守护机制。

【问题讨论】:

    标签: twisted twisted.application twistd


    【解决方案1】:

    使用 Twisted,作为 tac 文件,您的 HeartbeatClient 看起来像这样:

    from twisted.application.service import Application, Service
    from twisted.internet import reactor
    from twisted.internet.task import LoopingCall
    from twisted.internet.protocol import DatagramProtocol
    
    class HeartbeatClient(Service):
        def startService(self):
            self._call = LoopingCall(self._heartbeat)
            self._call.start(BEAT_PERIOD)
    
        def stopService(self):
            self._call.stop()
    
        def _heartbeat(self):
            port = reactor.listenUDP(0, DatagramProtocol())
            port.write('PyHB', (SERVER_IP, SERVER_PORT))
            port.stopListening()
    
    application = Application("PyHB")
    HeartbeatClient().setServiceParent(application)
    

    注意reactor.listenUDP 的使用,即使您只发送UDP 数据报,不接收任何数据报。 UDP实际上没有客户端和服务器的概念,它只有开放的端口。所有 UDP 端口都可以发送和接收数据报。这就是为什么只有reactor.listenUDP,而不是reactor.connectUDP

    除此之外,LoopingCall 为您提供所需的循环,并将代码放入自定义的 Service 子类中,您可以在适当的时间启动和停止循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多