2011-09-09 26 views
1

我正在寫由服務器的Python程序(使用雙絞線)和客戶(在不扭曲)非基於雙絞線運行Python腳本與twistd來

服務器部分使用雙絞線和雙絞線的application framework實現進程化並用Twistd啓動以進行守護。

在不同的服務器上運行的客戶端是一個簡單的Python腳本,沒有任何扭曲的東西(也沒有應用程序框架特定的東西)。它也應該作爲守護進程運行。供參考,這是來源:

#!/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 daemonize客戶端?因此,我會從客戶端創建一個Twisted應用程序。但是我看到的所有例子都是關於Twisted應用程序的,這些應用程序實現了一些扭曲的互聯網服務器的東西(比如在我的例子中是internet.UDPServer ...),這是我的客戶端不使用的。

那麼是否有可能使用Twistd作爲守護程序啓動我的客戶端,以及我必須做出什麼更改?我應該重寫客戶端以充分利用Twisted嗎?如果是的話,那裏有沒有類似的例子來說明如何編寫基於Twisted的網絡客戶端?

或者我必須爲客戶端使用不同的守護程序庫嗎?有一個good library for that,但我試圖保持一致併爲客戶端和服務器使用相同的守護進程機制。

回答

4

隨着扭曲的,作爲一個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子類中,可讓您在適當的時間啓動和停止循環。