2011-07-22 30 views
4

私はTwistedの新人です。私が持っている問題と同様の多くの関連記事を読んでいます。しかし、私は単純な問題を解決するために以前の答えを推定することができません。私はTwistedのFAQセクションを参照しました - 私はまだ理解できません。ツイスト - サーバーからクライアントにデータを送信

私の問題は、1つのポートでリッスンしているサーバーがあることです。「START」コマンドを受信すると、いくつかのクライアントと話したいと思います。例として、私は占いクッキーを提供する単一のクライアントを使用しました。しかし、私はサーバーコードでクライアントと話すことができません。私が間違っている場所を教えてもらえますか?ここでは、コードです:

from twisted.internet import reactor, protocol 
from twisted.internet.protocol import Protocol, Factory 

class FakeTelnet(Protocol): 
    def connectionMade(self): 
     print 'local connection made' 
     self.otherFact = protocol.ClientFactory() 
     self.otherFact.protocol = EchoClient 
     self.factory.clients.append(self.otherFact.protocol) 
     reactor.connectTCP('psrfb6',10999, self.otherFact) 

    def dataReceived(self, data): 

     if 'START' in data: 
      # send a command to cookie server. 
      for client in self.factory.clients: 
       client.transport.write('START\r\n') 

    def connectionLost(self): 
     print 'connection lost' 

class EchoClient(Protocol): 
    """Once connected, send a message, then print the result.""" 

    def connectionMade(self): 
     print "Connection to cookie server" 

    def dataReceived(self, data): 
     "As soon as any data is received, write it back." 
     print "Fortune Server said:", data 

    def connectionLost(self): 
     print "connection lost" 

    def send_stuff(data): 
     self.transport.write(data); 

class MyFactory(Factory): 
    protocol = FakeTelnet 
    def __init__(self, EchoClient): 
     self.clients = [] 
     self.otherCli = EchoClient 

reactor.listenTCP(5823, MyFactory(EchoClient)) 
reactor.run() 
+0

短い更新:私はこのよくある質問をチェックしました:http://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#Howdo他の人との間でコネクションを確立しようとしています。私は、FakeTelnetで確立されたクライアント接続をdataReceivedで利用できるようにしたい。どんな助けも非常に高く評価されます。ありがとうございました。 – user858302

答えて

5
class FakeTelnet(Protocol): 
    def connectionMade(self): 
     print 'local connection made' 
     self.otherFact = protocol.ClientFactory() 
     self.otherFact.protocol = EchoClient 

はここで、あなたはEchoClientクラスするself.otherFact.protocolを設定します。ここで

 self.factory.clients.append(self.otherFact.protocol) 

あなたはself.factory.clientsリストにEchoClientクラスを追加します。これにより、self.factory.clientsEchoClientクラスの繰り返しリストになることがあります。それだけで今までの輸送ではなく、クラス自体に接続して取得プロトコルクラスのインスタンスであるため、

def dataReceived(self, data): 
    if 'START' in data: 
     # send a command to cookie server. 
     for client in self.factory.clients: 
      client.transport.write('START\r\n') 

ここでは、一般的にNoneなりますEchoClient.transportに書き込みをしてみてください。

代わりにself.factory.clientsに接続インスタンスを追加してみてください。あなたはまた、FakeTelnet.connectionMadeにこのラインを持っているので、私が思うに、こうしたインスタンスを作成するために管理している:

reactor.connectTCP('psrfb6',10999, self.otherFact) 

しかし、あなたはself.factory.clientsリストに接続されているプロトコルを取得してみましょうだろう何もしていません。おそらく、あなたの代わりにこのようなself.otherFactを定義することができます。

class OtherFactory(ClientFactory): 
    protocol = EchoClient 

    def __init__(self, originalFactory): 
     self.originalFactory = originalFactory 

    def buildProtocol(self, addr): 
     proto = ClientFactory.buildProtocol(self, addr) 
     self.originalFactory.clients.append(proto) 
     return proto 

をあなたはまたいくつかの点でclientsリストから物事を削除することになるでしょう。おそらく、プロトコルのconnectionLostコールバックで:

class EchoClient(Protocol): 
    ... 
    def connectionLost(self, reason): 
     self.factory.originalFactory.clients.remove(self) 

最後に、あなたが行指向のデータを扱っている場合は、FakeTelnetのための基本クラスとしてtwisted.protocols.basic.LineOnlyReceiverを使用し、そのlineReceivedコールバックであなたのロジックを置きたいことがあります。 dataReceivedコールバックはデータ境界を保証しないため、"START"を含む単一の文字列は表示されません。たとえば、dataReceivedに2回、​​に1回、もう1つには"ART"を呼び出します。

関連する問題