I was hoping to avoid having to put something like AMP in place, because it looked a bit overkill for my case.
So I start my sniffer (in a thread) in my ServerFactory and I keep a dictionary of deferred for each line (corresponds to an emitter and a server port).
It allows me to call the messageToSend method corresponding to the proper server when receiving data.
Here is a code extract of what I implemented:
class Oldimon(Protocol):
def __init__(self, factory):
self.factory = factory
self.line = None
def connectionMade(self):
# Check the server port to get the line
# associated to this protocol
port = self.transport.getHost().port
self.line = LINES_PORT[port]
# Add the callback for this line
self.factory.deferred[self.line] = defer.Deferred()
self.factory.deferred[self.line].addCallback(self.messageToSend)
class OldimonFactory(ServerFactory):
def __init__(self, device, pcap_filter):
# pcapDataReceived callback is called everytime a message
# is received
reactor.callInThread(run_pcap, device, pcap_filter, self.pcapDataReceived)
# Dict with a deferred for each line
self.deferred = dict(zip(LINES_PORT.values(), [None] * len(LINES_PORT)))
def buildProtocol(self, addr):
return Oldimon(self)
def pcapDataReceived(self, data, line):
if self.deferred[line] is not None:
# Fire the callback for line
d, self.deferred[line] = self.deferred[line], None
d.callback(data)
oldimon_factory = OldimonFactory(device, pcap_filter)
for port in LINES_PORT.keys():
reactor.listenTCP(port, oldimon_factory)
reactor.run()
Le 1 mars 2013 à 15:31, Laurens Van Houtven <_@lvh.cc> a écrit :
Well, you'd presumably have a connection to each of the servers in the form of a client factory and a protocol instance. Then, every time you get a message, you figure out which protocol instance you want (the one for the appropriate server) and send a message to it. You could do that with self.transport.write, of course, but it would be much easier to just use a ready-made RPC thing.
One such RPC thing is AMP, which comes with Twisted. You can read more about it here:
http://amp-protocol.net/https://twistedmatrix.com/documents/current/core/howto/amp.html
You will probably end up having a command like HandlePacket or something (presumably you can come up with a more apt domain-specific name), and something close to self.servers[serverFor(packet.origin)].callRemote(HandlePacket, packet.data), or whatever.
I realize this is still pretty vague and high level, so feel free to ask more questions about the parts that are unclear :)
_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python