听听推送消息?

时间:2016-11-21 12:05:40

标签: c++ curl soap webservices-client

我必须无限期地收听网络服务的推送消息。我正在收听的Web服务会在内容发生更新时发送soap响应消息。收到消息后,我必须解析它并将其存储到结构中。以下是我的代码。

CURL *curl;
CURLcode res;
const char *onlineWebServiceRequest = "<?xml version=\"1.0\" encoding=\"utf-8\"?> <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">  <soap:Body>    <GetCitiesByCountry xmlns=\"http://www.webserviceX.NET\">  <CountryName>Netherlands</CountryName>     </GetCitiesByCountry>    </soap:Body>    </soap:Envelope>";

if(curl){

    curl_easy_setopt(curl, CURLOPT_URL, "http://www.webservicex.net/globalweather.asmx/GetCitiesByCountry" );

    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, onlineWebServiceRequest);  

    res = curl_easy_perform(curl);       
    // call some other method to parse the res
    curl_easy_cleanup(curl);    
} 

疑惑:  这是接收推送消息的正确方法吗?如果是的话,

上述代码不会检查与Web服务的连接状态。我该怎么检查?

如果不是,我可能使用开源的其他选项是什么?

提前致谢

1 个答案:

答案 0 :(得分:1)

最好检查错误。

为此,您必须启用CURLOPT_ERRORBUFFER选项。

curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);

并添加一个缓冲区(它必须至少CURL_ERROR_SIZE个字节大。)

char errbuf[CURL_ERROR_SIZE];

此外,您可以将CURLOPT_FAILONERROR设置为true,以强制curl将所有响应代码&gt; = 300转换为错误。

curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);

要从服务器获取实际输出,您需要设置一个函数来写入数据(CURLOPT_WRITEFUNCTION)和一块内存(CURLOPT_WRITEDATA)。

改编自[1][2]的完整示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <curl/curl.h>

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
  if(mem->memory == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;

  return realsize;
}

int main(void)
{
  curl_global_init(CURL_GLOBAL_ALL);

  /* init the curl session */ 
  CURL curl = curl_easy_init();
  if(curl) {
    CURLcode res;

    struct MemoryStruct chunk;

    chunk.memory = (char *)malloc(1);  /* will be grown as needed by the realloc above */ 
    chunk.size = 0;    /* no data at this point */ 

    char errbuf[CURL_ERROR_SIZE];

    /* specify URL to get */ 
    curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");

    /* send all data to this function  */ 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);

    /* we pass our 'chunk' struct to the callback function */ 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

    /* force curl to fail error when http code >= 300 */
    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);

    /* provide a buffer to store errors in */
    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);

    /* set the error buffer as empty before performing a request */
    errbuf[0] = 0;

    /* perform the request */
    res = curl_easy_perform(curl);

    /* if the request did not complete correctly, show the error
    information. if no detailed error information was written to errbuf
    show the more generic information from curl_easy_strerror instead.
    */
    if(res != CURLE_OK) {
      size_t len = strlen(errbuf);
      fprintf(stderr, "\nlibcurl: (%d) ", res);
      if(len)
        fprintf(stderr, "%s%s", errbuf,
                ((errbuf[len - 1] != '\n') ? "\n" : ""));
      else
        fprintf(stderr, "%s\n", curl_easy_strerror(res));
    }
    else {
      /*
       * Now, our chunk.memory points to a memory block that is chunk.size
       * bytes big and contains the remote file.
       *
       * Do something nice with it!
       */ 

      printf("%lu bytes retrieved\n", (long)chunk.size);
    }

    /* cleanup curl stuff */ 
    curl_easy_cleanup(curl);

    free(chunk.memory);

  }

  /* we're done with libcurl, so clean it up */ 
  curl_global_cleanup();

  return 0;
}