I need to be able to listen on one port (9000), and send to other servers on different ports (7777,8888,9999).
The code I wrote does work, but I'm not sure if it is the best method. It looks non-pythonic to continually use self.factory.factoryObjectList. I wish I could assign this to another value to clean up the code a little.
Is my method overkill? Can this be done in an easier way?
import sys
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ClientFactory, ServerFactory
from twisted.protocols.basic import LineReceiver
from twisted.python import log
class RX_Protocol(LineReceiver):
def dataReceived(self, data):
self.sendMessageToConnections(self.factory.factoryObjectList, data)
self.transport.write('sent \'%s\' to %d servers\n' % (data.strip(), self.countConnections(self.factory.factoryObjectList)))
def connectionMade(self):
self.transport.write('hello telnet user! Let\'s send a message to all connections\n')
def sendMessageToConnections(self, factoryObjectList, data):
for factoryObject in factoryObjectList: # iterate through list of factory objects, 1 for each server
for connection in factoryObject.factory.connections: # now iterate through the actual connections of each factory
connection.transport.write(data)
def countConnections(self, factoryObjectList):
counter = 0
for factoryObject in factoryObjectList:
if factoryObject.state == 'connected':
counter += 1
return counter
class RX_Factory(ServerFactory):
protocol = RX_Protocol
def __init__(self, factoryObjectList):
self.factoryObjectList = factoryObjectList
## TX Stuff ##
class TX_Protocol(Protocol):
def connectionMade(self):
self.factory.connections.append(self)
def connectionLost(self, reason):
self.factory.connections.remove(self)
class TX_Factory(ClientFactory): # subclass your factory of choice (Factory, ClientFactory, ServerFactory)
protocol = TX_Protocol
def __init__(self):
self.connections = []
# spawn these in new terminals using nc -l XXXX
servers = [('localhost', 7777),
('localhost', 8888),
('localhost', 9999)]
# servers = [('localhost', 7777)] # easier than opening 3 terminals
factoryObjectList = [] # will hold the multiple factories we use to connect to servers
# give us better STDOUT twisted logging
log.startLogging(sys.stdout)
for host, port in servers:
factoryObjectList.append(reactor.connectTCP(host, port, TX_Factory()))
reactor.listenTCP(9000, RX_Factory(factoryObjectList)) #RX_Factory now "knows" about connections to servers
reactor.run()