1
votes

Im trying to write a program that would be listening for data (simple text messages) on some port (say tcp 6666) and then pass them to one or more different protocols - irc, xmpp and so on. I've tried many approaches and digged the Internet, but I cant find easy and working solution for such task.

The code I am currently fighting with is here: http://pastebin.com/ri7caXih

I would like to know how to from object like:

ircf = ircFactory('asdfasdf', '#asdf666')

get access to self protocol methods, because this:

self.protocol.dupa1(msg)

returns error about self not being passed to active protocol object. Or maybe there is other, better, easier and more kosher way to create single reactor with multiple protocols and have actions triggeres when a message arrives on any of them, and then pass that message to other protocols for handling/processing/sending?

Any help will be highly appreciated!

3

3 Answers

5
votes

Here is sample code to read from multiple connections to port 9001 and write out to a connection on port 9000. You would need multiple "PutLine" implementations, one for XMPP, IRC, MSN, etc.

I used a global to store the output connection PutLine but you would want to create a more complex Factory object that would handle this instead.

#!/usr/bin/env python

from twisted.internet.protocol import Protocol, Factory
from twisted.internet.endpoints import clientFromString, serverFromString
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor

queue = []
putter = None

class GetLine(LineReceiver):
    delimiter = '\n'

    def lineReceived(self, line):
        queue.append(line)
        putter.have_data()
        self.sendLine(line)

class PutLine(LineReceiver):
    def __init__(self):
        global putter
        putter = self
        print 'putline init called %s' % str(self)

    def have_data(self):
        line = queue.pop()
        self.sendLine(line)


def main():
    f = Factory()
    f.protocol = PutLine
    endpoint = clientFromString(reactor, "tcp:host=localhost:port=9000")
    endpoint.connect(f)
    f = Factory()
    f.protocol = GetLine
    endpoint2 = serverFromString(reactor, "tcp:port=9001")
    endpoint2.listen(f)
    reactor.run()

if __name__ == '__main__':
    main()

Testing:

nc -l  9000
python test.py
nc 9001

Data entered form any number of nc 9001 (or netcat 9001) will appear on nc -l 9000.

1
votes

See doc/core/examples/chatserver.py. There they've added hooks to the Protocol's connectionMade and connectionLost methods to maintain a list of connected clients, and then it iterates through all of them when a message arrives to pass on.