如何使用Twisted连接两个程序

时间:2013-11-17 12:06:23

标签: python twisted panda3d

我在Twisted中有一个需要从echoclient获取输入的echoserver。 echocient是一个GUI(Panda3D)。客户端只需在单击按钮时发送短消息。

所以我有不定期发送的消息(仅在点击按钮时)。

如何建立永久连接(reactor.run()已在客户端程序的开头启动)并发送消息。

我不想在EchoClient / connectionMade中编写轮询机制。我看到了一个gtk +的例子,但无法将其转换为Panda。怎么去下面的代码根本不起作用,但让你知道我想要什么(基本上是永久连接,偶尔用户在按下按钮时发送一些内容)。

from direct.showbase.ShowBase import ShowBase
from direct.gui.DirectButton import DirectButton
from panda3d.core import Vec3
from direct.task import Task

from twisted.internet import protocol, reactor, defer
from twisted.internet.task import LoopingCall
from twisted.spread import pb

FRAMERATE = 32

class LoginDialog:
   def __init__(self, deferred):
     self.deferredResult = deferred

class EchoClient(ShowBase, protocol.Protocol):
   def __init__(self):
      ShowBase.__init__(self)

      self.echoer = echoer   
      self.button = DirectButton(pos = Vec3(.1,0,.1), text = "Send request",
               scale = .1, pad = (.5, .5),
               rolloverSound = None, clickSound = None,
               command = self.Request)

   def Request():
      self.echoer.transport.write("Message from client")

   def dataReceived(self, data):
       print "Server said: ", data

cf = pb.PBClientFactory()
cf.getRootObject().addCallback(EchoClient)
reactor.connectTCP("localhost", 17000, cf)
LoopingCall(taskMgr.step).start(1 / FRAMERATE)
reactor.run()

3 个答案:

答案 0 :(得分:1)

如果您使客户端和服务器成为同一进程的一部分,那么您将始终(好吧,几乎总是)能够将信息从一个传递到另一个。

如果您使客户端和服务器处理不同的进程,则可能没有满足您要求的解决方案。

总是 要执行某些事情以在两个进程之间建立连接,并且它总是有可能消失。遗憾。

答案 1 :(得分:0)

查看多处理:http://docs.python.org/2/library/multiprocessing.html

您可以启动和加入不同的进程以及它们之间的消息。

答案 2 :(得分:0)

我找到了答案。现在我有一个程序,一旦按下按钮就会向服务器发送消息。我使用ClientCreator创建了一个EchoClient。像这样:

      self.clientcreate = protocol.ClientCreator(reactor, EchoClient)
      self.clientcreate.connectTCP(host, port).addCallbacks(self.connectionMade,
               self.connectionFailed)

现在当我连接TCP并建立连接时,它会在成功时调用self.ConnectionMade。 因此,它还为EchoClient提供了功能。所以我可以存储它(self.client = echoclient),并在我想要时使用它(无法通过工厂实现)。

例如按钮调用函数Request,我可以直接使用transport.write命令,因为我现在有了客户端。所以self.client.transport.write('what')。

如果人们之前不理解我想要的东西,有更好的想法来完成这项工作,我希望看到他们的意见(我想学习)。

完整代码(仅限客户):

from twisted.internet import protocol, reactor, defer
from twisted.internet.task import LoopingCall

from direct.showbase.ShowBase import ShowBase
from direct.gui.DirectButton import DirectButton
from panda3d.core import Vec3
from direct.task import Task

FRAMERATE = 32

class ButtonDialog(ShowBase):
   def __init__(self):

      ShowBase.__init__(self)

      self.button = DirectButton(pos = Vec3(.1,0,.1), text = "Send request",
               scale = .1, pad = (.5, .5),
               rolloverSound = None, clickSound = None,
               command = self.Request) 

      host = "localhost"
      port = 17001

      self.clientcreate = protocol.ClientCreator(reactor, EchoClient)
      self.clientcreate.connectTCP(host, port).addCallbacks(self.connectionMade,
               self.connectionFailed)

   def connectionFailed(self, f):
       print "Connection Failed:", f
       reactor.stop()

   def connectionMade(self, echoclient):
       self.client = echoclient

   def Request(self):
       self.client.transport.write("Message from button")   

class EchoClient(protocol.Protocol):

   def dataReceived(self, data):
       print "Server said: ", data

   def connectionLost(self, err):
       print "Connection is lost: " + str(err)
       reactor.stop()

ButtonDialog()
LoopingCall(taskMgr.step).start(1 / FRAMERATE)
reactor.run()