2014-02-27 38 views
1

我正在創建一個將通過TCP連接接收的命令驅動的機器人。因此,我將有一個帶有方法的機器人類(例如sense(),drive()...)和用於TCP連接的類。如何處理TCP連接事件以便調用其他類中的方法?

爲了建立TCP連接,我查看了扭曲的例子。在客戶端,我已經寫了client.py腳本連接處理:

from twisted.internet import reactor, protocol 
import random 
from eventhook import EventHook 
import common 

#from Common.socketdataobjects import response 


# a client protocol 

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

def connectionMade(self): 
    self.transport.write("hello, world!") 
    #the server should be notified that the connection to the robot has been established 
    #along with robot state (position) 
    #eventConnectionEstablishedHook.fire() 

def dataReceived(self, data): 
    print "Server said:", data 
    self.transport.write("Hello %s" % str(random.randint(1,10))) 
    ''' 
    serverMessage = common.deserializeJson(data) 
    command = serverMessage.command 
    arguments = serverMessage.arguments 
    #here we get for example command = "DRIVE" 
    #arguments = {motor1Speed: 50, motor2Speed: 40} 
    instead of above response, used for testing purposes, 
    the commands should be extracted from the data and according to the command, 
    the method in Robot instance should be called. 
    When the command execution finishes, the self.transport.write() method should be called 
    to notify the server that the command execution finished 
    ''' 


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

class EchoFactory(protocol.ClientFactory): 
    protocol = EchoClient 
def clientConnectionFailed(self, connector, reason): 
    print "Connection failed - goodbye!" 
    reactor.stop() 

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


# this connects the protocol to a server runing on port 8000 

def initializeEventHandlers(connectionEstablishedHook): 
    global connection 
    connection.established = 0 
    global eventConnectionEstablishedHook 
    eventConnectionEstablishedHook = connectionEstablishedHook 

def main(): 
    f = EchoFactory() 
    reactor.connectTCP("localhost", 8000, f) 
    reactor.run() 

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

除了這個劇本,我有一個機器人類:

Class Robot(object(): 

    def __init(self)__: 
     self.position = (0,0) 

    def drive(self, speedMotor1, speedMotor2, driveTime) 
     updateMotor1State(speedMotor1) 
     updateMotor2State(speedMotor2) 
     time.sleep(driveTime) 
     #when the execution finished, the finish status should be sent to client in order to inform the server 
     return "Finished" 

    def sense(self) 
     #logic to get the data from the environment 

我想這樣做,是爲了接收來自TCP連接的數據(命令),然後調用Robot實例中的相應方法。有些程序可能需要較長的時間(如駕駛),所以我試圖用事件,但還沒有想出合適的方式TCP客戶機和機器人之間進行通信使用的事件:

if __name__ == '__main__': 
    robotController = Robot() 
    eventController = Controller() 
    connectionEstablishedHook = EventHook() 
    client.initializeEventHandlers(connectionEstablishedHook) 
    eventController.connection = connectionEstablishedHook 
    client.main() 

我試圖創建ClientMainProgram腳本,我想創建一個機器人實例,一個TCP客戶端實例,並使用事件實現它們之間的通信。

以前我已經設法使用Michael Foord's events pattern來實現一個更簡單的事件處理。如果有人能夠爲這個問題提供解決方案或任何可能有助於解決此問題的相似示例,我將非常感謝。

+0

查看XMLRPC,pickle,json,Pyro,HTTP,REST。它們存在。問題:函數的參數是什麼?你轉移回調,引用?你想實現自己的協議嗎? http://stackoverflow.com/a/21644326/1320237 – User

+0

我編輯了機器人psseudo函數以使其更加清晰。無論如何,從服務器收到的數據應該通過客戶端傳遞給機器人實例來控制機器人。機器人完成執行動作後,應將數據發送回服務器。 –

回答

1

事件很容易用常規的Python函數調用表示。

例如,如果你的方案是這樣的:

from twisted.internet.protocol import Protocol 

class RobotController(Protocol): 
    def __init__(self, robot): 
     self.robot = robot 

    def dataReceived(self, data): 
     for byte in data: 
      self.commandReceived(byte) 

    def commandReceived(self, command): 
     if command == "\x00": 
      # drive: 
      self.robot.drive() 
     elif command == "\x01": 
      # sense: 
      self.robot.sense() 
     ... 

(在本例中使用的協議的細節是有點偶然我拿起這個協議,因爲它很簡單,幾乎沒有任何的分析邏輯。對於您的實際應用,我建議您使用twisted.protocols.amp。)

然後,您需要做的就是確保robot屬性已正確初始化。您可以使用稍微更新的端點API輕鬆完成這項工作,該API可以替代工廠的使用:

from sys import argv 
from twisted.internet.endpoints import clientFromString, connectProtocol 
from twisted.internet.task import react 

def main(reactor, description): 
    robot = ... 
    endpoint = clientFromString(reactor, description) 
    connecting = connectProtocol(endpoint, RobotController(robot)) 
    def connected(controller): 
     ... 
    connecting.addCallback(connected) 
    return connecting 

react(main, argv[1:]) 
相關問題