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