React to unjoin packet - remove a client from this server

        :param packet: Packet from client that wants to join
        :type packet: paps.si.app.message.APPJoinMessage
        :param ip: Client ip address
        :type ip: unicode
        :param port: Client port
        :type port: int
        :rtype: None

def _do_unjoin_packet(self, packet, ip, port):
        """
        React to unjoin packet - remove a client from this server

        :param packet: Packet from client that wants to join
        :type packet: paps.si.app.message.APPJoinMessage
        :param ip: Client ip address
        :type ip: unicode
        :param port: Client port
        :type port: int
        :rtype: None
        """
        self.debug("()")
        device_id = packet.header.device_id

        if device_id <= Id.SERVER:
            self.error("ProtocolViolation: Invalid device id")
            return
        client = self._clients.get(device_id)
        if not client:
            self.error("ProtocolViolation: Client is not registered")
            return
        key = u"{}:{}".format(ip, port)
        if client['key'] != key:
            self.error(
                u"ProtocolViolation: Client key ({}) has changed: {}".format(
                    client['key'], key
                )
            )
            return

        # Packet info seems ok
        try:
            self.changer.on_person_leave(client['people'])
        except:
            self.exception("Failed to remove people")
            return

        # Forget client?
        del self._clients[device_id]
        del self._key2deviceId[key]
        del client