Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用REST代理(PHP)检查Azure队列是否存在_Php_Azure_Azure Storage_Azure Storage Queues - Fatal编程技术网

使用REST代理(PHP)检查Azure队列是否存在

使用REST代理(PHP)检查Azure队列是否存在,php,azure,azure-storage,azure-storage-queues,Php,Azure,Azure Storage,Azure Storage Queues,我正试图使用REST代理与Azure队列交互,这是提供的。虽然有大量的代码示例,但我想检查队列是否存在,以便在添加消息之前在必要时创建它 try { // setup connection string for accessing queue storage $connectionString = 'DefaultEndpointsProtocol=' . PROTOCOL . ';AccountName=' . ACCOUNT_NAME . ';AccountKey=' . ACCOU

我正试图使用REST代理与Azure队列交互,这是提供的。虽然有大量的代码示例,但我想检查队列是否存在,以便在添加消息之前在必要时创建它

try {
  // setup connection string for accessing queue storage
  $connectionString = 'DefaultEndpointsProtocol=' . PROTOCOL . ';AccountName=' . ACCOUNT_NAME . ';AccountKey=' . ACCOUNT_KEY;

  // create queue REST proxy
  $queueRestProxy = ServicesBuilder::getInstance()->createQueueService($connectionString);

  // create message
  $queueRestProxy->createMessage(QUEUE_NAME, 'Hello World!');

} catch(ServiceException $e){
  // Handle exception based on error codes and messages.
  // Error codes and messages are here: 
  // http://msdn.microsoft.com/en-us/library/windowsazure/dd179446.aspx
  $code = $e->getCode();
  $error_message = $e->getMessage();
  echo $code.": ".$error_message."<br />";
}

我应该在创建消息之前简单地包含队列创建代码,还是有更有效的方法在与队列交互之前确定队列是否存在?

通常在其他Windows Azure SDK中,我见过类似
createQueueIfNotExists
的方法,我很惊讶PHP SDK中缺少此方法。基本上,这个函数的工作方式是尝试创建一个队列。如果存储器中存在同名队列,则存储服务将抛出
冲突(409)
错误

由于此函数不存在,您可以执行相同的操作,即尝试在其自己的try/catch块内创建队列并检查错误代码。如果错误代码为409,则继续,否则将重新引发异常。类似下面的代码:

try {
  // setup connection string for accessing queue storage
  $connectionString = 'DefaultEndpointsProtocol=' . PROTOCOL . ';AccountName=' . ACCOUNT_NAME . ';AccountKey=' . ACCOUNT_KEY;
    // create queue REST proxy
        $queueRestProxy = ServicesBuilder::getInstance()->createQueueService($connectionString);
  try {
    // now try to create the queue.
$queueRestProxy->createQueue(QUEUE_NAME);
  } catch(ServiceException $e){
    $code = $e->getCode();
    //Now check if the $code is 409 - Conflict. If the error code is indeed 409, you continue otherwise throw the error
  }
  // create message
  $queueRestProxy->createMessage(QUEUE_NAME, 'Hello World!');

} catch(ServiceException $e){
  // Handle exception based on error codes and messages.
  // Error codes and messages are here: 
  // http://msdn.microsoft.com/en-us/library/windowsazure/dd179446.aspx
  $code = $e->getCode();
  $error_message = $e->getMessage();
  echo $code.": ".$error_message."<br />";
}
试试看{
//设置用于访问队列存储的连接字符串
$connectionString='DefaultEndpointsProtocol='.PROTOCOL.';AccountName='.ACCOUNT_NAME.';AccountKey='.ACCOUNT_KEY;
//创建队列REST代理
$queueRestProxy=ServicesBuilder::getInstance()->createQueueService($connectionString);
试一试{
//现在尝试创建队列。
$queueRestProxy->createQueue(队列名称);
}捕获(ServiceException$e){
$code=$e->getCode();
//现在检查$code是否为409-Conflict。如果错误代码确实为409,则继续,否则将抛出错误
}
//创建消息
$queueRestProxy->createMessage(队列名称“Hello World!”);
}捕获(ServiceException$e){
//根据错误代码和消息处理异常。
//错误代码和消息如下:
// http://msdn.microsoft.com/en-us/library/windowsazure/dd179446.aspx
$code=$e->getCode();
$error_message=$e->getMessage();
echo$code.“:”$error_message.“
”; }

另外,我没有尝试执行代码,因此它可能会抛出错误。这只是给你一个想法。

我在下面发布了一个完整的答案,以便于人们一眼就能看到答案

我应该在创建队列之前简单地包含队列创建代码吗 还是有更有效的方法来确定 队列在与它交互之前是否存在

有两种方法来解决这个问题

  • 在创建消息之前,请包含
    createQueue
    语句,但请按照指定的
    try catch
    块将此语句包装,即忽略409个错误,但对任何其他类型的错误引发异常

    有关信息,在创建消息之前包含
    createQueue
    语句时

    • 如果已存在同名队列元数据 与现有队列关联的与传递给
      createQueue
      语句,则不会创建队列,并且 队列REST代理将在内部接收一个204(无内容)状态代码,但此 响应代码不提供给程序员。所以 本质上,
      createQueue
      语句不会导致 在此场景中引发的错误/异常

    • 如果已存在同名队列元数据 与现有队列关联的与传递的队列不相同 对于
      createQueue
      语句,则不会创建队列,并且 队列REST代理将收到一个409(冲突)状态代码,并将引发 允许程序员访问此响应代码和相关
      QueueReadyExists
      消息的异常

    资料来源:-见备注部分

  • 创建一个
    queueExists
    函数并调用它来决定是否需要创建队列。这里有一种实现这种功能的方法

    public function queueExists($queueRestProxy, $queueName) {
      $result = FALSE;
      $listQueuesResult = $queueRestProxy->listQueues();
      $queues = $listQueuesResult->getQueues();
      foreach($queues as $queue) {
        if ($queue->getName() === $queueName) {
          $result = TRUE;
          break;
        }
      }
      return $result;        
    }
    

  • 希望这对别人有帮助

    @Guarav-谢谢你的回复。经过一些测试后,似乎对createQueue(QUEUE_NAME)的多个连续调用不会导致抛出ServiceException,因此Azure内部似乎以静默方式处理此问题。也许这就是为什么他们不在SDK中发布createQueueIfNotExists或queueExists方法的原因。我不这么认为。此外,所有其他SDK都具有此功能。有关.Net:,请参见此处。所有SDK都是REST API的包装器,因此我不认为这是原因。诚然,我的观察结果与创建队列REST API页()上的“备注”部分不一致,这与您的回答一致,即,如果队列存在且元数据不匹配,则返回409,如果队列存在且元数据匹配,则返回204。但是,我没有看到这些响应代码的真实性,因为没有引发异常。有趣的是,有一个名为“testCreateQueueWithExistingQueue”的单元测试,它调用createQueue($queueName)两次,并期望只创建一个队列(没有任何异常处理)-请参阅我看到的。谢谢你的文档链接,你说得对(今天学到了一些新东西:)。因此,如果您尝试创建一个名称与现有队列匹配且元数据不不同的队列,则返回的状态代码为204,这实际上不是异常情况,因此您不会得到错误。我认为,每当存储服务发送大于或等于400的状态代码时,您都会收到服务异常。否则将不会提出任何例外。
    public function queueExists($queueRestProxy, $queueName) {
      $result = FALSE;
      $listQueuesResult = $queueRestProxy->listQueues();
      $queues = $listQueuesResult->getQueues();
      foreach($queues as $queue) {
        if ($queue->getName() === $queueName) {
          $result = TRUE;
          break;
        }
      }
      return $result;        
    }