问题
there is a similar question here, but no clear answers.
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()
回答1:
Your method looks typical to me.
Take a look at SO: What is the correct way to access a protocols transport in Twisted? (which also links to another SO: Persistent connection in Twisted) there is a note about the newer "endpoint" system, you might like its style better.
来源:https://stackoverflow.com/questions/23525667/sending-data-to-multiple-factories-receieved-from-a-different-factory