[Twisted-Python] How to dispatch message to different servers

Benjamin BERTRAND beenje at gmail.com
Fri Mar 1 16:52:56 EST 2013


Thanks for the answer!

I was hoping to avoid having to put something like AMP in place, because it looked a bit overkill for my case.
I think I actually found a way :-)

I guess I can use the same factory to start all my servers. 
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 <_ at 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 :)
> 
> 
> On Thu, Feb 28, 2013 at 10:59 PM, Benjamin BERTRAND <beenje at gmail.com> wrote:
> Hi,
> 
> I have to replace a piece of software that sniffs the traffic on one interface. It gets different messages that are each associated to a specific emitter.
> On the same machine, one server is started for each emitter (on a different port).
> And the application is just supposed to use the proper server to send the messages captured (to a client on another machine).
> 
> Not sure if it's clear, but basically if I have 2 emitters A and B, I'll start 2 servers (a and b).
> My sniffer will get messages A1, A2, B1, B2, B3...
> I have to pass messages A1, A2 to server a, that will just send them to the client (if it is connected of course).
> And B1, B2, B3 to server b.
> I don't need any buffering. If no client is connected, messages captured are just discarded.
> 
> To sniff the network, I want to use pylibpcap or pcapy.
> I found this example to make it work with twisted: http://dound.com/2009/09/integrating-twisted-with-a-pcap-based-python-packet-sniffer/
> 
> Starting several servers that use the same protocol is not a problem.
> But how do I pass the messages captured to the right server?
> How do I make the link between the function sniffing the network and the servers?
> 
> Thanks
> 
> Benjamin
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
> 
> 
> 
> -- 
> cheers
> lvh
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20130301/2a0256ea/attachment-0001.htm 


More information about the Twisted-Python mailing list