34

I have used twisted to implement a client. It works fine. Now I want to be able to pass command line arguments to it, so I need to implement a twisted plugin. I have performed many searches to find resources that would show how to convert the program to a plugin. However I couldn't find exactly what I as looking for.

Here is a related part of my client.py code:

import sys
import time
import os
import errno
import re
from stat import *
global runPath

runPath = '/home/a02/Desktop/'

from twisted.python import log
from GlobalVariables import *
from twisted.internet import reactor, threads, endpoints
from time import sleep
from twisted.internet.protocol import ClientFactory# , Protocol
from twisted.protocols import basic
import copy


class MyChat(basic.LineReceiver):
    def connectionMade(self):
        print "Connected to the server!"
        EchoClientFactory.buildClientObject(self.factory, self)
        self.runPythonCommands = RunPythonCommands ()
        return

    def connectionLost(self, reason):
        print "Lost Connection With Server!"
        #self.factory.clients.remove(self)
        #self.transport.loseConnection()
        print 'connection aborted!'
        #reactor.callFromThread(reactor.stop)
        reactor.stop ()
        return

    def lineReceived(self, line):
        #print "received", repr(line)
        line = line.strip ()
        if line == "EOF":
            print "Test Completed"
        self.factory.getLastReceivedMsg (line)
        exeResult = self.runPythonCommands.runPythonCommand(line.strip())

        self.sendLine(exeResult)
        EchoClientFactory.lastReceivedMessage = ""
        EchoClientFactory.clientObject[0].receivedMessages = []
        return

    def message (self, line):
        self.sendLine(line)
        #print line
        return


class EchoClientFactory(ClientFactory):
    protocol = MyChat
    clientObject = []
    lastReceivedMessage = ''

    def buildClientObject (self, newClient):
        client = Client ()
        self.clientObject.append(client)
        self.clientObject[0].objectProtocolInstance = newClient

        return

    def getLastReceivedMsg (self, message):
        self.lastReceivedMessage = message
        self.clientObject [0].lastReceivedMsg = message
        self.clientObject[0].receivedMessages.append (message)
        return 
    def connectionLost (self):
        reactor.stop()
        return

    def clientConnectionFailed(self, connector, reason):
        print 'Connection failed. Reason:', reason
        connector.connect () 
        return

Here is what I wrote for my client_plugin.py:

from zope.interface import implements
from twisted.python import usage
from twisted.plugin import IPlugin
from twisted.application.service import IServiceMaker
from twisted.application.internet import TCPServer
from twisted.spread import pb
from slave.client import EchoClientFactory,MyChat, Client, RunPythonCommands, MyError, line


class Options(usage.Options):
    optParameters = [["port", "p", 8789, "The port number to listen on."], ["host", "h", "192.168.47.187", "The host to connect to"]]

class MyServiceMaker(object):
    implements(IServiceMaker, IPlugin)
    tapname = "echoclient"
    description = "Echo Client"
    options = Options

    def makeService(self, options):
        clientfactory = pb.PBServerFactory(EchoClientFactory ())
        return TCPServer(options["host"],int(options["port"]), clientfactory)

serviceMaker = MyServiceMaker()

I have used the same folder hierarchy mentioned in the documentation. As I haven't been able to find enough examples of plugins on the web, I'm really stuck at this point. I would appreciate any help. Could anybody tell me how to change the code? Thank you in advance.

undercovertek
  • 148
  • 1
  • 11
user823743
  • 2,152
  • 3
  • 21
  • 31

3 Answers3

1

Should you perhaps be using the tac files to run it from command line?

http://twistedmatrix.com/documents/12.2.0/core/howto/application.html#auto5

Then using your MyChat class should be easier in another program...

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120
  • I consider that your answer would better be placed in the comments section, in my opinion. –  Apr 30 '17 at 12:48
0

You have to return a main service object from your MyServiceMaker().makeService method. Try adding from twisted.internet import service then in makeService add this at the beginning: top_service = service.Multiservice() Create the TCPServer service: tcp_service = TCPServer(...) Add it to the top service: tcp_service.setServiceParent(top_service) Then return the top service: return top_service

You may also need to take a look at this excellent series of tutorials from Dave Peticolas (article n°16 is the one which is useful for your problem)

Oyono
  • 377
  • 1
  • 8
  • Could you please provide a detailed explanation and not an outline of your suggested approach? –  Apr 30 '17 at 12:46
0

Just follow this links for docs and help:

twistedmatrix - docs

twisted.readthedocs.io -docs

from __future__ import print_function

from twisted.internet import reactor
from twisted.web.client import Agent
from twisted.web.http_headers import Headers

agent = Agent(reactor)

d = agent.request(
    'GET',
    'http://example.com/',
    Headers({'User-Agent': ['Twisted Web Client Example']}),
    None)

def cbResponse(ignored):
    print('Response received')
d.addCallback(cbResponse)

def cbShutdown(ignored):
    reactor.stop()
d.addBoth(cbShutdown)

reactor.run()

Output:

C:\Python27>python.exe twist001.py
Response received