Okay, I've made some huge progress, I think with my Telnet connection stuff. I'm curious what the Twisted pros think of this..syntax, if it is correct, etc. Here is what I'm going for, I want to have this application running, which provides an XML-RPC interface for 'controlling' it. The server, right now, can start Telnet clients at the request of XML-RPC clients. This seems to work, however, I'd also like to be able to stop said Telnet clients, or see which ones are running, etc. I can't wrap my brain around how to accomplish those bits of functionality. I've included the .tac file below for reference.
<br><br>Thanks so much for your assistance!<br><br>-Don<br><br><br>#Try to build a Twisted Connector Service the twisted way<br>from twisted.application import internet, service<br>from twisted.web import resource, server, static, xmlrpc
<br>import re, time<br><br><br>from EventTypes import Event<br>connectiontypes = {'TelnetConnection':'A telnet client connection.', 'FileTailConnection':'Facilitates tailing a log file'}<br><br><br>class Connection:<br>&nbsp;&nbsp;&nbsp; def __init__(self,name):
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Constructor<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.name=name<br>&nbsp;&nbsp;&nbsp; #print &quot;Connection name: %s&quot; % <a href="http://self.name">self.name</a><br>&nbsp;&nbsp;&nbsp; self.status=False<br><br>&nbsp;&nbsp;&nbsp; def setStatus (self,status):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.status=status
<br><br>####################<br># TCP Client Stuff<br>####################<br>from twisted.internet.protocol import Protocol, ReconnectingClientFactory<br>from twisted.conch.telnet import Telnet<br><br><br>##########################
<br># Telnet Clients<br>##########################<br>class TelnetClient(Telnet):<br>&nbsp;&nbsp;&nbsp; &quot;TelnetClient class.&quot; <br>&nbsp;&nbsp;&nbsp; def connectionMade(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #print &quot;connection made to %s&quot; % <a href="http://self.factory.name">
self.factory.name</a><br>&nbsp;&nbsp;&nbsp; #if the cmd variable was set in the calling factory, lets iterate over it.<br>&nbsp;&nbsp;&nbsp; if self.factory.cmd:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for cmd in self.factory.cmd:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if &quot;sleep&quot; in cmd:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #print 
re.compile('(?P&lt;sleeptime&gt;(\d+))').search(cmd).group('sleeptime')<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleeptime = int(re.compile('(?P&lt;sleeptime&gt;(\d+))').search(cmd).group('sleeptime'))<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep(sleeptime)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.write(cmd)<br>&nbsp;&nbsp;&nbsp; <br><br>&nbsp;&nbsp;&nbsp; def write(self, data):<br>&nbsp;&nbsp;&nbsp; #print data<br>&nbsp;&nbsp;&nbsp; Telnet._write(self, data+&quot;\r\n&quot;)<br><br><br>&nbsp;&nbsp;&nbsp; def dataReceived(self, data):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;received:&quot;, data
<br>&nbsp;&nbsp;&nbsp; #always send data to the eventQueue<br>&nbsp;&nbsp;&nbsp; self.factory.eventQueue.insert(Event(data, <a href="http://self.factory.name">self.factory.name</a>))<br>&nbsp;&nbsp;&nbsp; #check if we should send any commands based on data received<br>
&nbsp;&nbsp;&nbsp; if self.factory.expect:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #check if any of the expect dictionary keys are in data<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for key in self.factory.expect.keys():&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if key in data:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for cmd in self.factory.expect
[key]:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if &quot;sleep&quot; in cmd:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleeptime = int(re.compile('(?P&lt;sleeptime&gt;(\d+))').search(cmd).group('sleeptime'))<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep(sleeptime)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.write(cmd)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br><br><br>class TelnetConnection(Connection, ReconnectingClientFactory):<br>&nbsp;&nbsp;&nbsp; &quot;Telnets to host:port and executes cmd. cmd&quot;<br>
&nbsp;&nbsp;&nbsp; protocol = TelnetClient<br>&nbsp;&nbsp;&nbsp; def&nbsp; __init__(self, name, eventQueue, cmd=None, expect=None): <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Connection.__init__(self, name)<br>&nbsp;&nbsp;&nbsp; self.cmd = cmd<br>&nbsp;&nbsp;&nbsp; self.expect = expect<br>&nbsp;&nbsp;&nbsp; self.eventQueue = eventQueue
<br>&nbsp;&nbsp;&nbsp; <br><br>&nbsp;&nbsp;&nbsp; <br><br>&nbsp;&nbsp;&nbsp; def clientConnectionFailed(self, connector, reason):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'connection failed:', reason.getErrorMessage()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br><br>&nbsp;&nbsp;&nbsp; def clientConnectionLost(self, connector, reason):
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'connection lost:', reason.getErrorMessage()<br><br><br>class ManagerService(service.Service):<br>&nbsp;&nbsp;&nbsp; def __init__(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass<br><br>&nbsp;&nbsp;&nbsp; # some XML-RPC function calls for twisted server<br>&nbsp;&nbsp;&nbsp; def stop(self):
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 'Shutdown initiated'<br><br>&nbsp;&nbsp;&nbsp; def getConnectionTypes(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;Return connection types&quot;&quot;&quot;<br>&nbsp;&nbsp;&nbsp; return connectiontypes<br><br>&nbsp;&nbsp;&nbsp; def xmlrpc_getActiveConnections(self):
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;Return all active connections&quot;&quot;&quot;<br><br>&nbsp;&nbsp;&nbsp; def getConnectionStatus(self, connection):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return &quot;connection status&quot;<br><br><br>&nbsp;&nbsp;&nbsp; def getResource(self):<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;Return sum of arguments.&quot;&quot;&quot;<br>&nbsp;&nbsp;&nbsp; r = resource.Resource()<br>&nbsp;&nbsp;&nbsp; x = xmlrpc.XMLRPC()<br>&nbsp;&nbsp;&nbsp; x.xmlrpc_stop = self.stop<br>&nbsp;&nbsp;&nbsp; x.xmlrpc_getConnectionStatus = self.getConnectionStatus
<br>&nbsp;&nbsp;&nbsp; x.xmlrpc_startTelnet = self.startTelnet<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r.putChild('RPC2', x)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return r<br><br>&nbsp;&nbsp;&nbsp; def startTelnet(self, host, port, name, queue, command, script):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from twisted.internet import reactor
<br>&nbsp;&nbsp;&nbsp; from EventQueue import Queue<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Create the Event Queue object<br>&nbsp;&nbsp;&nbsp; self.queue = queue<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.queue = Queue()<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reactor.connectTCP(host, int(port), TelnetConnection(name,self.queue
,command,script))<br>&nbsp;&nbsp;&nbsp; return &quot;%s started&quot; % name<br><br><br>#create an application instance<br>application = service.Application('connectorservice', uid=1, gid=1)<br>m = ManagerService()<br>serviceCollection = 
service.IServiceCollection(application)<br>internet.TCPServer(7090, server.Site(m.getResource())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ).setServiceParent(serviceCollection)<br>