带有 pexpect 实例错误的简单扭曲服务器 (twistd .tap)

发布于 2024-08-22 03:00:41 字数 5086 浏览 9 评论 0原文

我一直在创建一个使用twisted 发送和接收xml 的异步服务器套接字。

该应用程序运行得很好!但因为我的主要目标是将其嵌入 init.d 脚本并使其在后台运行,所以我决定将其转换为“twisted 应用程序”,以便使用 twind 运行它,使用

# from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory
from twisted.protocols.basic import LineOnlyReceiver
from twisted.application import internet, service

from xml.etree import ElementTree as ET

from aMuleClass import amulecmd

class DialogueProtocol(LineOnlyReceiver):
    def connectionMade(self):
        print "Connected: %s" % self.transport.getPeer().host
def lineReceived(self, line):
    parsed= ET.XML(line)
    if parsed.attrib['type'] == 'request':
        if parsed.attrib['prompt'] == 'results':
            self.transport.write(self.factory.mule.results())
        elif parsed.attrib['prompt'] == 'downloads':
            self.transport.write(self.factory.mule.downloads())
        else:
            print "Invalid request: %s\n" % line
    else:
        query= parsed.attrib['value']
        if parsed.attrib['type'] == 'search':
            print "must search for %s" % query
            self.factory.mule.search(query)
        elif parsed.attrib['type'] == 'cancel':
            print "must cancel %s" % query
            self.factory.mule.command("cancel %s" % query)
        elif parsed.attrib['type'] == 'download':
            print "must download %s" % query
            self.factory.mule.command("download %s" % query)

class DialogueProtocolFactory(ServerFactory):
def __init__(self):
    self.protocol= DialogueProtocol
    self.mule= amulecmd()

def main():
factory= DialogueProtocolFactory()
port = 14000
#
daemon= internet.TCPServer(port, factory)
application= service.Application("aMuleSocket")
#
daemon.setServiceParent(application)

if __name__ == '__main__':
main()

“twistd -noy 文件”运行它(调试)工作完美。 问题是当我想为我的脚本设置背景时! (“twistd -y file”)套接字没有响应,日志中充满了来自 pexpect 的错误,该错误是在我的 amulecmd 类中导入的... pexpect 与终端提示应用程序通信并将答案返回到套接字..

日志文件:

2010/02/17 19:54 +0200 [-] Log opened.
2010/02/17 19:54 +0200 [-] twistd 2.5.0 (/usr/bin/python 2.5.2) starting up
2010/02/17 19:54 +0200 [-] reactor class: <class          'twisted.internet.selectreactor.SelectReactor'>
2010/02/17 19:54 +0200 [-] Loading aMuleSocket.tac...
2010/02/17 19:54 +0200 [-] Starting parent
2010/02/17 19:54 +0200 [-] Loaded.
2010/02/17 19:54 +0200 [-] __builtin__.DialogueProtocolFactory starting on 2000
2010/02/17 19:54 +0200 [-] Starting factory <__builtin__.DialogueProtocolFactory instance at 0x82dbd8c>
2010/02/17 19:54 +0200 [__builtin__.DialogueProtocolFactory] Connected: 192.168.0.2
2010/02/17 19:54 +0200 [DialogueProtocol,0,192.168.0.2] Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.5/site-packages/twisted/python/log.py", line 48, in      callWithLogger
 return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/log.py", line 33, in callWithContext
 return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/context.py", line 59, in callWithContext
 return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/context.py", line 37, in callWithContext
 return func(*args,**kw)
--- <exception caught here> ---
File "/usr/lib/python2.5/site-packages/twisted/internet/selectreactor.py", line 139, in _doReadOrWrite
 why = getattr(selectable, method)()
File "/usr/lib/python2.5/site-packages/twisted/internet/tcp.py", line 362, in doRead
 return self.protocol.dataReceived(data)
File "/usr/lib/python2.5/site-packages/twisted/protocols/basic.py", line 149, in dataReceived
 self.lineReceived(line)
File "aMuleSocket.tac", line 19, in lineReceived
 self.transport.write(self.factory.mule.downloads())
File "/home/hecyra/amule_scripts/amule-remote-read-only/server/aMuleClass.py", line 60, in downloads
 list= self.command('show DL').splitlines()
File "/home/hecyra/amule_scripts/amule-remote-read-only/server/aMuleClass.py", line 42, in command
 self.prompt()
File "/home/hecyra/amule_scripts/amule-remote-read-only/server/aMuleClass.py", line 27, in prompt
 self.process.expect('aMulecmd')
File "/usr/lib/python2.5/site-packages/pexpect.py", line 1064, in expect
 return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
File "/usr/lib/python2.5/site-packages/pexpect.py", line 1116, in expect_list
 c = self.read_nonblocking (self.maxread, timeout)
File "/usr/lib/python2.5/site-packages/pexpect.py", line 656, in read_nonblocking
 if not self.isalive():
File "/usr/lib/python2.5/site-packages/pexpect.py", line 914, in isalive
raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but   there was no child process. Did someone else call waitpid() on our process?')
pexpect.ExceptionPexpect: isalive() encountered condition where "terminated" is 0,            but there was no child process. Did someone else call waitpid() on our process?

它可能是什么?我所需要的只是这个脚本的背景:(看起来很简单

I have been creating an async server socket that sends and recives xml using twisted.

The application works great! but because my main objective was to embed it in an init.d script and make it run in the background i decided to transform it in a "twisted application" in order to run it using twistd

# from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory
from twisted.protocols.basic import LineOnlyReceiver
from twisted.application import internet, service

from xml.etree import ElementTree as ET

from aMuleClass import amulecmd

class DialogueProtocol(LineOnlyReceiver):
    def connectionMade(self):
        print "Connected: %s" % self.transport.getPeer().host
def lineReceived(self, line):
    parsed= ET.XML(line)
    if parsed.attrib['type'] == 'request':
        if parsed.attrib['prompt'] == 'results':
            self.transport.write(self.factory.mule.results())
        elif parsed.attrib['prompt'] == 'downloads':
            self.transport.write(self.factory.mule.downloads())
        else:
            print "Invalid request: %s\n" % line
    else:
        query= parsed.attrib['value']
        if parsed.attrib['type'] == 'search':
            print "must search for %s" % query
            self.factory.mule.search(query)
        elif parsed.attrib['type'] == 'cancel':
            print "must cancel %s" % query
            self.factory.mule.command("cancel %s" % query)
        elif parsed.attrib['type'] == 'download':
            print "must download %s" % query
            self.factory.mule.command("download %s" % query)

class DialogueProtocolFactory(ServerFactory):
def __init__(self):
    self.protocol= DialogueProtocol
    self.mule= amulecmd()

def main():
factory= DialogueProtocolFactory()
port = 14000
#
daemon= internet.TCPServer(port, factory)
application= service.Application("aMuleSocket")
#
daemon.setServiceParent(application)

if __name__ == '__main__':
main()

Running this with "twistd -noy file" (debug) works PERFECTLY.
The problem is when i want to background my script! ("twistd -y file") the socket dosent respond and the log gets filled with errors from pexpect, which is imported in my amulecmd class...
pexpect communicates with a terminal-prompt application and returns the answers to the socket..

logfile:

2010/02/17 19:54 +0200 [-] Log opened.
2010/02/17 19:54 +0200 [-] twistd 2.5.0 (/usr/bin/python 2.5.2) starting up
2010/02/17 19:54 +0200 [-] reactor class: <class          'twisted.internet.selectreactor.SelectReactor'>
2010/02/17 19:54 +0200 [-] Loading aMuleSocket.tac...
2010/02/17 19:54 +0200 [-] Starting parent
2010/02/17 19:54 +0200 [-] Loaded.
2010/02/17 19:54 +0200 [-] __builtin__.DialogueProtocolFactory starting on 2000
2010/02/17 19:54 +0200 [-] Starting factory <__builtin__.DialogueProtocolFactory instance at 0x82dbd8c>
2010/02/17 19:54 +0200 [__builtin__.DialogueProtocolFactory] Connected: 192.168.0.2
2010/02/17 19:54 +0200 [DialogueProtocol,0,192.168.0.2] Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python2.5/site-packages/twisted/python/log.py", line 48, in      callWithLogger
 return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/log.py", line 33, in callWithContext
 return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/context.py", line 59, in callWithContext
 return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib/python2.5/site-packages/twisted/python/context.py", line 37, in callWithContext
 return func(*args,**kw)
--- <exception caught here> ---
File "/usr/lib/python2.5/site-packages/twisted/internet/selectreactor.py", line 139, in _doReadOrWrite
 why = getattr(selectable, method)()
File "/usr/lib/python2.5/site-packages/twisted/internet/tcp.py", line 362, in doRead
 return self.protocol.dataReceived(data)
File "/usr/lib/python2.5/site-packages/twisted/protocols/basic.py", line 149, in dataReceived
 self.lineReceived(line)
File "aMuleSocket.tac", line 19, in lineReceived
 self.transport.write(self.factory.mule.downloads())
File "/home/hecyra/amule_scripts/amule-remote-read-only/server/aMuleClass.py", line 60, in downloads
 list= self.command('show DL').splitlines()
File "/home/hecyra/amule_scripts/amule-remote-read-only/server/aMuleClass.py", line 42, in command
 self.prompt()
File "/home/hecyra/amule_scripts/amule-remote-read-only/server/aMuleClass.py", line 27, in prompt
 self.process.expect('aMulecmd')
File "/usr/lib/python2.5/site-packages/pexpect.py", line 1064, in expect
 return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
File "/usr/lib/python2.5/site-packages/pexpect.py", line 1116, in expect_list
 c = self.read_nonblocking (self.maxread, timeout)
File "/usr/lib/python2.5/site-packages/pexpect.py", line 656, in read_nonblocking
 if not self.isalive():
File "/usr/lib/python2.5/site-packages/pexpect.py", line 914, in isalive
raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but   there was no child process. Did someone else call waitpid() on our process?')
pexpect.ExceptionPexpect: isalive() encountered condition where "terminated" is 0,            but there was no child process. Did someone else call waitpid() on our process?

What could it be?? all i need is to background this script :( looked easy

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最初的梦 2024-08-29 03:00:41

您在守护进程之前生成一个子进程。守护进程之后,该子进程现在是 init 的子进程,而不是您的守护进程的子进程。

您需要从twisted.application.service import Service 子类化并在startService 中生成子进程,该子进程将在守护进程后调用。

Á La: 带有多处理工作线程的 Twisted 网络客户端?

编辑:实现

我无法完全测试这一点,因为我没有您的 amulecmd,但请尝试类似这样的操作:

#!/usr/bin/env python
# vim:ai:et:ts=2:sw=2:bg=dark
from twisted.internet import protocol
from twisted.protocols.basic import LineOnlyReceiver
from twisted.application import service


from xml.etree import ElementTree as ET

from aMuleClass import amulecmd

class DialogueProtocol(LineOnlyReceiver):
  def connectionMade(self):
    print "Connected: %s" % self.transport.getPeer().host
  def lineReceived(self, line):
    parsed= ET.XML(line)
    if parsed.attrib['type'] == 'request':
      if parsed.attrib['prompt'] == 'results':
        self.transport.write(self.factory.mule.results())
      elif parsed.attrib['prompt'] == 'downloads':
        self.transport.write(self.factory.mule.downloads())
      else:
        print "Invalid request: %s\n" % line
    else:
      query= parsed.attrib['value']
      if parsed.attrib['type'] == 'search':
        print "must search for %s" % query
        self.factory.mule.search(query)
      elif parsed.attrib['type'] == 'cancel':
        print "must cancel %s" % query
        self.factory.mule.command("cancel %s" % query)
      elif parsed.attrib['type'] == 'download':
        print "must download %s" % query
        self.factory.mule.command("download %s" % query)

class MyService(service.Service):
  def __init__(self,port=14000):
    self.port = port
  def startService(self):
    self.factory = protocol.Factory()
    self.factory.protocol = DialogueProtocol
    from twisted.internet import reactor
    reactor.callWhenRunning(self.startListening)
  def startListening(self):
    self.factory.mule = amulecmd()
    from twisted.internet import reactor
    self.listener = reactor.listenTCP(self.port,self.factory)
    print "Started listening"
  def stopService(self):
    self.listener.stopListening()

if __name__ == '__main__':
  pass
else:
  application = service.Application("aMuleSocket")
  services = service.IServiceCollection(application)
  MyService().setServiceParent(services)

You're spawning a child process before daemonizing. After daemonizing that child is now a child of init, and not a child of your daemon.

You need to subclass from twisted.application.service import Service and spawn the child process in startService, which will be called after daemonizing.

Á La: Twisted network client with multiprocessing workers?

Edit: implementation

I can't test this entirely as I don't have your amulecmd, but try something more like this:

#!/usr/bin/env python
# vim:ai:et:ts=2:sw=2:bg=dark
from twisted.internet import protocol
from twisted.protocols.basic import LineOnlyReceiver
from twisted.application import service


from xml.etree import ElementTree as ET

from aMuleClass import amulecmd

class DialogueProtocol(LineOnlyReceiver):
  def connectionMade(self):
    print "Connected: %s" % self.transport.getPeer().host
  def lineReceived(self, line):
    parsed= ET.XML(line)
    if parsed.attrib['type'] == 'request':
      if parsed.attrib['prompt'] == 'results':
        self.transport.write(self.factory.mule.results())
      elif parsed.attrib['prompt'] == 'downloads':
        self.transport.write(self.factory.mule.downloads())
      else:
        print "Invalid request: %s\n" % line
    else:
      query= parsed.attrib['value']
      if parsed.attrib['type'] == 'search':
        print "must search for %s" % query
        self.factory.mule.search(query)
      elif parsed.attrib['type'] == 'cancel':
        print "must cancel %s" % query
        self.factory.mule.command("cancel %s" % query)
      elif parsed.attrib['type'] == 'download':
        print "must download %s" % query
        self.factory.mule.command("download %s" % query)

class MyService(service.Service):
  def __init__(self,port=14000):
    self.port = port
  def startService(self):
    self.factory = protocol.Factory()
    self.factory.protocol = DialogueProtocol
    from twisted.internet import reactor
    reactor.callWhenRunning(self.startListening)
  def startListening(self):
    self.factory.mule = amulecmd()
    from twisted.internet import reactor
    self.listener = reactor.listenTCP(self.port,self.factory)
    print "Started listening"
  def stopService(self):
    self.listener.stopListening()

if __name__ == '__main__':
  pass
else:
  application = service.Application("aMuleSocket")
  services = service.IServiceCollection(application)
  MyService().setServiceParent(services)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文