Beispiel #1
0
    def _handle_sm_feature(self, features):
        """
        Enable or resume stream management.

        If no SM-ID is stored, and resource binding has taken place,
        stream management will be enabled.

        If an SM-ID is known, and the server allows resumption, the
        previous stream will be resumed.
        """
        if 'stream_management' in self.xmpp.features:
            # We've already negotiated stream management,
            # so no need to do it again.
            return False
        if not self.sm_id:
            if 'bind' in self.xmpp.features:
                enable = stanza.Enable(self.xmpp)
                enable['resume'] = self.allow_resume
                enable.send()
                self.enabled = True
                self.handled = 0
                self.unacked_queue.clear()

                waiter = Waiter(
                    'enabled_or_failed',
                    MatchMany([
                        MatchXPath(stanza.Enabled.tag_name()),
                        MatchXPath(stanza.Failed.tag_name())
                    ]))
                self.xmpp.register_handler(waiter)
                result = yield from waiter.wait()
        elif self.sm_id and self.allow_resume and 'bind' not in self.xmpp.features:
            self.enabled = True
            resume = stanza.Resume(self.xmpp)
            resume['h'] = self.handled
            resume['previd'] = self.sm_id
            resume.send()

            # Wait for a response before allowing stream feature processing
            # to continue. The actual result processing will be done in the
            # _handle_resumed() or _handle_failed() methods.
            waiter = Waiter(
                'resumed_or_failed',
                MatchMany([
                    MatchXPath(stanza.Resumed.tag_name()),
                    MatchXPath(stanza.Failed.tag_name())
                ]))
            self.xmpp.register_handler(waiter)
            result = yield from waiter.wait()
            if result is not None and result.name == 'resumed':
                return True
        return False