[Twisted-Python] Issues with creating switchboards with twisted.words.protocols.msn

Jean-Paul Calderone exarkun at divmod.com
Fri Jun 27 08:57:58 EDT 2008

On Fri, 27 Jun 2008 14:47:03 +0200, Hermann Kaser <hermann.kaser at gmail.com> wrote:
>Hello all,
>I'm trying to write an MSN client but I've run into a problem: for
>some reason when I create a Switchboard and try to invite someone it
>sends the join command and the invitation command all together and the
>MSN server doesn't answer any of them. Here's the relevant bits of the
>code I have:
>class Switchboard(msn.SwitchboardClient):
>   def connectionMade(self):
>        self.key = self.factory.key
>        self.sessionID = self.factory.sessionID
>        self.userHandle = self.factory.userHandle
>        self.invite = self.factory.invite
>        msn.SwitchboardClient.connectionMade(self)
>        d = self.inviteUser(self.invite)
>        d.addCallback(self.Invited)
>    def Invited(self, *args):
>        print 'Running reply callback'
>And this is the ngrep stream after the XFR request
># send transfer request
>T -> [AP]
>  CHG 6 NLN..XFR 7 SB..
># get transfer response
>T -> [AP]
>  XFR 7 SB CKI 712606054.15830117.2511186..
>T -> [AP]
>  CHG 6 NLN 0..
>T -> [AP]
>  ILN 6 NLN [redacted]@hotmail.com [redacted screenname] 1073741856..
>T -> [AP]
>  USR 1 [my email] 712606054.15830117.2511186..CAL 2 [email of who i
>want to invite]..
>If I try to do the same process with pidgin for example, the stream
>looks exactly the same except the USR and CAL command are on separate
>packets, and the server responds to the USR command before the client
>sends the CAL command.
>Can anyone help me out figuring this out? I know you can send more
>than one command per packet, as seen in the first packet of the ngrep
>stream I posted, so I don't see why it wouldn't work to send the USR
>and CAL command together, but I suspect that not all commands may be
>stuck together. I stuck a time.sleep(20) between the calling
>msn.SwitchboardClient.connectionMade(self) and
>self.inviteUser(self.invite) to see if it was a timing issue but what
>happens is that the USR command gets buffered, and only when the
>script tries to send the CAL command does the socket actually write it

The way to do this is to let the reactor do some I/O in between the
calls.  Sleeping is almost the right idea (for debugging, at least),
but you need to do it in a way that cooperates with the reactor.  Try
putting the inviteUser call into a separate function and delaying its
execution a bit:

    def connectionMade(self):
        reactor.callLater(1, self._doinvite)

    def _doinvite(self):
        d = self.inviteUser(self.invite)

If this works, then you may have demonstrated that USR and CAL
cannot be combined like this.  In that case, I'd say it's a bug
in Twisted's MSN support - it's the protocol's job to know things
like this, so the protocol should automatically buffer the CAL
if it knows a USR is going to be sent with it.

>Any help on this would be greatly appreciated, I've been digging
>around the documentation and the code but I can't seem to figure out
>why it's buffering the USR command and I don't know enough about the
>MSN protocol to know which commands need a unique packet and which
>ones can go with others.

It'd be interesting to see if pidgin has code to specifically avoid
combining USR and CAL (or USR and anything else).


More information about the Twisted-Python mailing list