Hello everyone,

I wrote a small example that listens for xmpp msgs in a thread. The main program calls a function that blocks (using Condition.wait) until a msg has been received and then returns the msg. When a msg arrives, it is put in a variable in the thread's object, it then calls the notify() attr on the Condition object. For some reason, this doesn't work, the thread gets the msg, tries to notify the Condition object, fails because the lock has not been acquired yet and blocks. I tried ignoring the failure, thinking that since it has not been acquired yet then when it is, it will get the msg right away and never call Condition.wait, thus not causing any problems, but this does not work either. Does someone know what I am doing wrong? I attached the code to this msg.

Thank you,
Gabriel
# Copyright (c) 2001-2006 Twisted Matrix Laboratories.
# See LICENSE for details.

import sys
from twisted.internet import reactor
from twisted.names.srvconnect import SRVConnector
from twisted.words.xish import domish, xpath
from twisted.words.protocols.jabber import xmlstream, client, jid

PRESENCE = '/presence' # this is an global xpath query to use in an observer
MESSAGE = '/message'   # message xpath
IQ = '/iq'             # iq xpath

class XMPPClientConnector(SRVConnector):
    def __init__(self, reactor, domain, factory):
        SRVConnector.__init__(self, reactor, 'xmpp-client', domain, factory)


    def pickServer(self):
        host, port = SRVConnector.pickServer(self)

        if not self.servers and not self.orderedServers:
            # no SRV record, fall back..
            port = 5222

        return host, port



class Client(object):

    def __init__(self, client_jid, secret, dest=None):
        """
        """
        self.dest = dest
        f = client.XMPPClientFactory(client_jid, secret)
        f.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT, self.connected)
        f.addBootstrap(xmlstream.STREAM_END_EVENT, self.disconnected)
        f.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, self.authenticated)
        f.addBootstrap(xmlstream.INIT_FAILED_EVENT, self.init_failed)
        connector = XMPPClientConnector(reactor, client_jid.host, f)
        connector.connect()

    def rawDataIn(self, buf):
        print "RECV: %s" % unicode(buf, 'utf-8').encode('ascii', 'replace')

    def rawDataOut(self, buf):
        print "SEND: %s" % unicode(buf, 'utf-8').encode('ascii', 'replace')

    def connected(self, xs):
        """
        """
        print 'Connected.'

        self.xmlstream = xs

        # Log all traffic
        xs.rawDataInFn = self.rawDataIn
        xs.rawDataOutFn = self.rawDataOut


    def disconnected(self, xs):
        """
        """
        print 'Disconnected.'
        try:
            reactor.stop()
        except:
            pass

    def authenticated(self, xs):
        """
        """
        def sendPresence():
            presence = domish.Element((None, 'presence'))
            xs.send(presence)

        def sendMsg(user, res=None):
            msg = domish.Element(("jabber:client", "message"))
            msg["to"] = "%...@localhost%s" % (user, "/" + res if res else "")
            body = msg.addElement("body", content = "Hello world %s" % res if res else "")
            subject = msg.addElement("subject", content = "will this be displayed?")
            thread = msg.addElement("thread", content = "this shouldn't be displayed")
            xs.send(msg)


        print "Authenticated."

        xs.addObserver(PRESENCE, self.onPresence, 1)
#        xs.addObserver(IQ, self.onIq, 1)
        xs.addObserver(MESSAGE, self.onMessage, 1)

        reactor.callLater(0, sendPresence)

        if(self.dest):
            reactor.callLater(2, sendMsg, self.dest, "toto")
            reactor.callLater(4, sendMsg, self.dest, "titi")

        #msg = domish.Element(("jabber:client", "message"))
        #msg["to"] = "grosse...@localhost"
        #body = msg.addElement("body", content = "Hello world")
        #subject = msg.addElement("subject", content = "will this be displayed?")
        #thread = msg.addElement("thread", content = "this shouldn't be displayed")
        #xs.send(msg)

        #msg = domish.Element(("jabber:client", "iq"))
        #msg["to"] = "ser...@localhost"
        #msg["id"] = "666"
        #xs.send(msg)

        #msg = domish.Element(("jabber:client", "presence"))
        #msg["to"] = "grosse...@localhost"
        #msg["type"] = "subscribe"
        #xs.send(msg)

        #reactor.callLater(5, xs.sendFooter)

    def onMessage(self, msg):
        """
        Act on the message stanza that has just been received.
        """
        # return to sender
        #msg = create_reply(msg)
        #self.xmlstream.send(msg) # send the modified domish.Element
        pass

#    def onIq(self, iq):
#        """
#        Act on the iq stanza that has just been received.

#        """
#        iq = create_reply(iq)
#        self.xmlstream.send(iq)

    def onPresence(self, prs):
        """
        Act on the presence stanza that has just been received.
        """
        t = xpath.XPathQuery("/presence").queryForNodes(prs)[0].getAttribute("type")
        if(t == "subscribe"):
            presence = self.toResponse(prs, "subscribed")
            self.xmlstream.send(presence)

    def init_failed(self, failure):
        """
        """
        print "Initialization failed."
        print failure

        self.xmlstream.sendFooter()

    def toResponse(self, stanza, stanzaType=None):
        """
        Create a response stanza from another stanza.

        This takes the addressing and id attributes from a stanza to create a (new,
        empty) response stanza. The addressing attributes are swapped and the id
        copied. Optionally, the stanza type of the response can be specified.

        @param stanza: the original stanza
        @type stanza: L{domish.Element}
        @param stanzaType: optional response stanza type
        @type stanzaType: C{str}

        @return: the response stanza.
        @rtype: L{domish.Element}
        """

        toAddr = stanza.getAttribute('from')
        fromAddr = stanza.getAttribute('to')
        stanzaID = stanza.getAttribute('id')

        response = domish.Element((None, stanza.name))
        if toAddr:
            response['to'] = toAddr
        if fromAddr:
            response['from'] = fromAddr
        if stanzaID:
            response['id'] = stanzaID
        if type:
            response['type'] = stanzaType

        return response


client_jid = jid.JID(sys.argv[1])
secret = sys.argv[2]
try:
    print "sys.argv[3] = %s" % sys.argv[3]
    dest = sys.argv[3]
except:
    dest = None

c = Client(client_jid, secret, dest)

reactor.run()
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to