ROS是如何实现XMLRPC的

发布时间:
来源: 电子工程世界

XMLRPC的代码在后的_comm-noet-develulitiesxmlrpcpp路径下。

还好,整个工程不算太大。XMLRPC分成客户端和服务器端两大部分。

咱们先看客户端,主要代码在XmlRpcClient.cpp文件里。

擒贼先擒王,XmlRpcClient.cpp文件中最核心的函数就是execu,用于执行远程调用,代码如下。

// Execute the named procedure on the remote server.
// Pas should be an array of the arguments f the method.
// Returns true if the request was sent and a result received (although the result might be a fault).
bool XmlRpcClient::execute(const char* method, XmlRpcValue const& params, XmlRpcValue& result)
{
  XmlRpcUtil::log(1, "XmlRpcClient::execute: method %s (_connectionState %s).", method, connectionStateStr(_connectionState));


  // This is not a thre-safe operation, if you want to do multithreng, use separate
  // clients for eh thread. If you want to protect youelf from multiple threads
  // accessing the same client, replace this code with a real mutex.
  if (_executing)
    return false;


  _executing = true;
  ClearFlagOnExit cf(_executing);


  _sendAttempts = 0;
  _isFault = false;


  if ( ! setupConnection())
    return false;


  if ( ! generateRequest(method, params))
    return false;


  result.clear();
  double msTime = -1.0;   // Process until exit is cal
  _disp.work(msTime);


  if (_connectionState != IDLE || ! parseResponse(result)) {
    _header = "";
    return false;
  }


  // close() if server does not supports HTTP1.1
  // otherwise, reusing the socket to write leads to a SIGPE because
  // the remote server could shut down the corresponding socket.
  if (_header.find("HTTP/1.1 200 OK", 0, 15) != 0) {
    close();
  }


  XmlRpcUtil::log(1, "XmlRpcClient::execute: method %s completed.", method);
  _header = "";
  _response = "";
  return true;
}

它首先调用setupConnection()函数与服务器端建立连接。

连接成功后,调用generateRequest()函数生成发送请求报文。

XMLRPC请求报文的头部又交给generateHeader()函数做了,代码如下。

// Prepend http headers
std::string XmlRpcClient::generateHeader(size_t length) const
{
  std::string header = 
    "POST " + _uri + " HTTP/1.1rn"
    "User-Agent: ";
  header += XMLRPC_VERSION;
  header += "rnHost: ";
  header += _host;


  char buff[40];
  std::snprintf(buff,40,":%drn", _port);


  header += buff;
  header += "Content-Type: text/xmlrnContent-length: ";


  std::snprintf(buff,40,"%zurnrn", length);
  return header + buff;
}

主体部分则先将远程调用的方法和参数变成XML格式,generateRequest()函数再将头部和主体组合成完整的报文,如下:

std::string header = generateHeader(body.length());
_request = header + body;

把报文发给服务器后,就开始静静地等待。

一旦接收到服务器返回的报文后,就调用parseResponse函数解析报文数据,也就是把XML格式变成纯净的数据格式。

我们发现,XMLRPC使用了socket功能实现客户端和服务器。

我们搜索socket这个单词,发现它原始的意思是插座。这非常形象,建立连接实现通信就像把插头插入插座。

虽说XMLRPC也是ROS的一部分,但它毕竟只是一个基础功能,我们会用即可,暂时不去探究其实现细节,

文章来源于: 电子工程世界 原文链接

本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。