2014-09-30 50 views
1

我目前正試圖將基於Twisted的應用程序轉換爲Twistedd Twisted Application Framework(TAC)。twistd TCPServer的應用程序(.tac)不能正常工作,而普通的twisted .py與listenTCP一起工作

如果我啓動.py,應用程序可以工作,但不能與「twistd -noy zmq2tcp.tac」守護程序一起使用。 的ZMQ連接似乎正確打開,但如果開始使用TAC文件不會偵聽端口2323

請解釋我爲什麼在這種情況下,listenTCP工作,但不是internet.TCPServer

的zmq2tcp.tac文件:

#!/usr/bin/python 
# **- encoding: utf-8 -** 
from twisted.application import internet, service 
from twisted.application.service import Application 

from txzmq import ZmqFactory, ZmqEndpoint, ZmqSubConnection, ZmqPushConnection 

from zmq2tcp import * 

LISTEN_PORT = 2323 

class ListenService(service.Service): 
    def __init__(self): 
     self.zf = ZmqFactory() 
     self.minidoFactory = MinidoServerFactory() 

    def startService(self): 
     self.sube = ZmqEndpoint('connect', 'tcp://localhost:5557') 
     self.push = ZmqEndpoint('connect', 'tcp://localhost:5558') 
     self.subconn = ZmqSubConnection(self.zf, self.sube) 
     self.subconn.subscribe('') 

     # Create the resource 
     self.minidoFactory.pushconn = ZmqPushConnection(self.zf, self.push) 
     self.subconn.gotMessage = self.minidoFactory.send2tcp 
     return internet.TCPServer(LISTEN_PORT, self.minidoFactory) 

    def stopService(self): 
     del self.sube 
     del self.push 
     del self.subconn 

application = Application('ZMQ2TCP') 
service = ListenService() 
service.setServiceParent(application) 

的zmq2tcp.py文件:

#!/usr/bin/env python 
# **- encoding: utf-8 -** 
""" 
    Minido-Unleashed is a set of programs to control a home automation 
    system based on minido from AnB S.A. 

    Please check http://kenai.com/projects/minido-unleashed/ 

    This program is free software: you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation, either version 3 of the License, or 
    (at your option) any later version. 

    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
    GNU General Public License for more details. 

    You should have received a copy of the GNU General Public License 
    along with this program. If not, see <http://www.gnu.org/licenses/>. 

    *** 

    This program connects to a STOMP server, and allow dual way communication 
    with the minido bus, checking the validity of the packet before sending. 
""" 

############################################################################### 
from __future__ import print_function 
from twisted.application import internet, service 
from twisted.internet.protocol import Protocol, ReconnectingClientFactory 
from twisted.internet.protocol import Factory 


# Other imports 
import datetime 
import time 
import sys 
import msgpack 

# minido 
from protocol import * 

# txZMQ 
from txzmq import ZmqFactory, ZmqEndpoint, ZmqPubConnection, ZmqSubConnection, ZmqPushConnection 

MINIDO_LISTEN_PORT = 2323 

class MinidoServerFactory(Factory): 
    def __init__(self): 
     self.connections = [] 

    def startedConnecting(self, connector): 
     print('Started to connect.') 

    def buildProtocol(self, addr): 
     return MinidoProtocol(self) 

    def clientConnectionLost(self, connector, reason): 
     print('Lost connection. Reason:', reason) 
     ReconnectingClientFactory.clientConnectionLost(self, connector, reason) 

    def clientConnectionFailed(self, connector, reason): 
     print('Connection failed. Reason:', reason) 
     ReconnectingClientFactory.clientConnectionFailed(self, connector, 
                 reason) 
    def recv_message(self, message): 
     print(': TCP to STOMP : %s' % (' '.join(map(lambda i: '{0:02X}'.format(i),message)))) 
     pushconn.push(msgpack.packb(message)) 

    def send2tcp(self, rawmessage, tag): 
     message = msgpack.unpackb(rawmessage) 
     if type(message) is tuple: 
      print(": STOMP to %i TCP client(s) : %s" % (
       len(self.connections), 
       ' '.join(map(lambda i: '{0:02X}'.format(i),message)))) 
      for conn in self.connections: 
       conn.send_data(message) 

if __name__ == '__main__': 
    from twisted.internet import reactor 
    zf = ZmqFactory() 
    minidoFactory = MinidoServerFactory() 
    sube = ZmqEndpoint('connect', 'tcp://localhost:5557') 
    subconn = ZmqSubConnection(zf, sube) 
    subconn.subscribe('') 

    subconn.gotMessage = minidoFactory.send2tcp 

    push = ZmqEndpoint('connect', 'tcp://localhost:5558') 
    minidoFactory.pushconn = ZmqPushConnection(zf, push) 
    reactor.listenTCP(MINIDO_LISTEN_PORT, minidoFactory) 
    reactor.run() 
+0

這裏的大部分代碼都是無關的。將來,請儘可能多地做診斷,創建一個http://sscce.org/供其他人查看。 – Glyph 2014-10-01 03:36:11

回答

1

的問題是,在你ListenService.startService你是創建和返回 a TCPServer服務,但你不是開始那個服務。

IService.startService不返回一個值,所以而不是return internet.TCPServer(LISTEN_PORT, self.minidoFactory),做internet.TCPServer(LISTEN_PORT, self.minidoFactory).startService()

雖然這存在一個明顯的問題,那就是您的stopService將不記得以後要停止的地方。這將是更好地考慮此因素,以創建TCPServer儘快和啓動/停止它與您的服務一起,就像這樣:

class ListenService(service.Service): 
    def __init__(self): 
     self.zf = ZmqFactory() 
     self.minidoFactory = MinidoServerFactory() 
     self.tcpService = internet.TCPServer(LISTEN_PORT, self.minidoFactory) 

    def startService(self): 
     self.sube = ZmqEndpoint('connect', 'tcp://localhost:5557') 
     self.push = ZmqEndpoint('connect', 'tcp://localhost:5558') 
     self.subconn = ZmqSubConnection(self.zf, self.sube) 
     self.subconn.subscribe('') 

     # Create the resource 
     self.minidoFactory.pushconn = ZmqPushConnection(self.zf, self.push) 
     self.subconn.gotMessage = self.minidoFactory.send2tcp 
     self.tcpService.startService() 

    def stopService(self): 
     del self.sube 
     del self.push 
     del self.subconn 
     return self.tcpService.stopService() 
0

首先,非常感謝你爲這個完美的答案。 以下是我發現也在起作用的解決方法。 但是我並不完全理解下面的解決方案,而更喜歡你的解決方案和解釋,所以我將它標記爲「一」。

#!/usr/bin/python 
# **- encoding: utf-8 -** 
from twisted.application import internet, service 
from twisted.application.service import Application 
from twisted.internet import reactor 

from txzmq import ZmqFactory, ZmqEndpoint, ZmqSubConnection, ZmqPushConnection 

from zmq2tcp import * 

LISTEN_PORT = 2323 

class ListenService(service.Service): 
    def __init__(self): 
     self.zf = ZmqFactory() 
     self.minidoFactory = MinidoServerFactory() 

    def startService(self): 
     self.sube = ZmqEndpoint('connect', 'tcp://localhost:5557') 
     self.push = ZmqEndpoint('connect', 'tcp://localhost:5558') 
     self.subconn = ZmqSubConnection(self.zf, self.sube) 
     self.subconn.subscribe('') 

     # Create the resource 
     self.minidoFactory.pushconn = ZmqPushConnection(self.zf, self.push) 
     self.subconn.gotMessage = self.minidoFactory.send2tcp 
     self._port = reactor.listenTCP(LISTEN_PORT, self.minidoFactory) 

    def stopService(self): 
     del self.sube 
     del self.push 
     del self.subconn 

application = Application('ZMQ2TCP') 
service = ListenService() 
service.setServiceParent(application) 
相關問題