Запускать не основанный на Twisted скрипт Python, демонизированный с помощью twistd - PullRequest
1 голос
/ 09 сентября 2011

Я пишу программу на Python, состоящую из сервера (использующего Twisted) и клиента (без Twisted)

Серверная часть реализована с использованием Twisted и Twisted прикладной инфраструктуры и запущена с 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-приложение из клиента. Но все примеры, которые я видел, касались приложений Twisted, в которых реализованы некоторые вещи из интернет-сервера Twisted (например, в моем случае internet.UDPServer ...), которые мой клиент не использует.

Так можно ли использовать Twistd для запуска моего клиента в качестве демона, и какие изменения я должен внести? Должен ли я переписать клиента, чтобы в полной мере использовать Twisted? Если да, есть ли похожие примеры, как написать клиент Twisted на основе сети?

Или мне нужно использовать другую библиотеку daemonize для клиента? хорошая библиотека для этого , но я пытаюсь быть последовательным и использовать один и тот же механизм демонизации для клиента и сервера.

1 Ответ

4 голосов
/ 09 сентября 2011

При использовании 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 позволяет запускать и останавливатьцикл в соответствующее время.

...