2009-10-31 96 views
3

我已经写了一个基于扭曲的服务器,我想用扭曲来测试它。测试扭曲的应用程序 - 加载客户端

但我想写一个负载测试,同时开始一堆请求。

但我相信,我没有得到扭转,主要是客户端的概念,因为我stucked这个问题:

from twisted.internet import reactor, protocol 
from threading import Thread 
from twisted.protocols.basic import LineReceiver 

__author__="smota" 
__date__ ="$30/10/2009 17:17:50$" 

class SquitterClient(LineReceiver): 

    def connectionMade(self): 
     self.sendLine("message from " % threading.current_thread().name); 
     pass 

    def connectionLost(self, reason): 
     print "connection lost" 

    def sendMessage(self, msg): 
     for m in [ "a", "b", "c", "d", "e"]: 
      self.sendLine(msg % " - " % m); 

class SquitterClientFactory(protocol.ClientFactory): 
    protocol = SquitterClient 

    def clientConnectionFailed(self, connector, reason): 
     print "Connection failed - goodbye!" 
     reactor.stop() 

    def clientConnectionLost(self, connector, reason): 
     print "Connection lost - goodbye!" 
     reactor.stop() 

def createAndRun(): 
    f = SquitterClientFactory() 
    reactor.connectTCP("localhost", 4010, f) 
    reactor.run(installSignalHandlers=0) 

# this connects the protocol to a server runing on port 8000 
def main(): 
    for n in range(0,10): 
     th=Thread(target=createAndRun) 
     th.start() 

# this only runs if the module was *not* imported 
if __name__ == '__main__': 
    main() 

socket_client.py:35: DeprecationWarning:反应器已经运行了 !因为扭曲的8.0
reactor.run(installSignalHandlers = 0)

我缺少这个特性已经被废弃 ?

如何测试它?

谢谢

塞缪尔

回答

9

的直接原因为你的失败是你学尝试调用run()的反应堆上多次。你应该只调用run()一次。我认为你期待有多个反应堆,每个反应堆都在自己的线程中,但实际上你只有一个反应堆。坏事是拥有多个反应器是困难的或不可能的 - 好处是它也是不必要的。事实上,你甚至不需要多个线程。您可以在一个反应​​器中复用多个客户端连接,就像您可以监听多个连接一样。

修改您的示例代码,像下面这样的应该工作。关键的想法是,你不需要多个反应堆并行地完成任务。无论如何,唯一能够与常规Python实现并行的是I/O。

from twisted.internet import reactor, protocol 
from twisted.protocols.basic import LineReceiver 

__author__="smota" 
__date__ ="$30/10/2009 17:17:50$" 

class SquitterClient(LineReceiver): 
    def connectionMade(self): 
     self.messageCount = 0 
     # The factory provides a reference to itself, we'll use it to enumerate the clients 
     self.factory.n += 1 
     self.name = "Client %d" %self.factory.n 

     # Send initial message, and more messages a bit later 
     self.sendLine("Client %s starting!" % self.name); 
     reactor.callLater(0.5, self.sendMessage, "Message %d" %self.messageCount) 

    def connectionLost(self, reason): 
     print "connection lost" 

    def sendMessage(self, msg): 
     for m in [ "a", "b", "c", "d", "e"]: 
      self.sendLine("Copy %s of message %s from client %s!" % (m, msg, self.name)) 
     if self.factory.stop: 
      self.sendLine("Client %s disconnecting!" % self.name) 
      self.transport.loseConnection() 
     else: 
      self.messageCount += 1 
      reactor.callLater(0.5, self.sendMessage, "Message %d" %self.messageCount) 

class SquitterClientFactory(protocol.ClientFactory): 
    protocol = SquitterClient 

    def __init__(self): 
     self.n = 0 
     self.stop = False 

    def stopTest(): 
     self.stop = True 

    def clientConnectionFailed(self, connector, reason): 
     print "Connection failed - goodbye!" 

    def clientConnectionLost(self, connector, reason): 
     print "Connection lost - goodbye!" 

# this connects the protocol to a server running on port 8000 
def main(): 
    # Create 10 clients 

    f = SquitterClientFactory() 
    for i in range(10): 
     reactor.connectTCP("localhost", 8000, f) 

    # Schedule end of test in 10 seconds 
    reactor.callLater(10, f.stopTest) 

    # And let loose the dogs of war 
    reactor.run() 

# this only runs if the module was *not* imported 
if __name__ == '__main__': 
    main() 
+2

您可能还想指出多个/线程/也不是必需的。 – 2009-11-01 14:20:33

+1

添加关于线程的注释也是不必要的。 – 2009-11-01 14:34:42