service_client.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009, Willow Garage, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution.
11  * * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "ros/service_client.h"
30 #include "ros/connection.h"
31 #include "ros/service_manager.h"
32 #include "ros/service.h"
33 
34 namespace ros
35 {
36 
38  : is_shutdown_(false)
39 { }
40 
42 {
43  shutdown();
44 }
45 
47 {
48  if (!is_shutdown_)
49  {
50  if (!persistent_)
51  {
52  is_shutdown_ = true;
53  }
54 
55  if (server_link_)
56  {
57  server_link_->getConnection()->drop(Connection::Destructing);
58  server_link_.reset();
59  }
60  }
61 }
62 
64 {
65  // Non-persistent connections are always valid
66  if (!persistent_)
67  {
68  return true;
69  }
70 
71  if (is_shutdown_)
72  {
73  return false;
74  }
75 
76  if (!server_link_)
77  {
78  return false;
79  }
80 
81  return server_link_->isValid();
82 }
83 
84 ServiceClient::ServiceClient(const std::string& service_name, bool persistent, const M_string& header_values, const std::string& service_md5sum)
85 : impl_(new Impl)
86 {
87  impl_->name_ = service_name;
88  impl_->persistent_ = persistent;
89  impl_->header_values_ = header_values;
90  impl_->service_md5sum_ = service_md5sum;
91 
92  if (persistent)
93  {
94  impl_->server_link_ = ServiceManager::instance()->createServiceServerLink(impl_->name_, impl_->persistent_, impl_->service_md5sum_, impl_->service_md5sum_, impl_->header_values_);
95  }
96 }
97 
99 {
100  impl_ = rhs.impl_;
101 }
102 
104 {
105 
106 }
107 
108 bool ServiceClient::call(const SerializedMessage& req, SerializedMessage& resp, const std::string& service_md5sum)
109 {
110  if (service_md5sum != impl_->service_md5sum_)
111  {
112  ROS_ERROR("Call to service [%s] with md5sum [%s] does not match md5sum when the handle was created ([%s])", impl_->name_.c_str(), service_md5sum.c_str(), impl_->service_md5sum_.c_str());
113 
114  return false;
115  }
116 
118 
119  if (impl_->persistent_)
120  {
121  if (!impl_->server_link_)
122  {
123  impl_->server_link_ = ServiceManager::instance()->createServiceServerLink(impl_->name_, impl_->persistent_, service_md5sum, service_md5sum, impl_->header_values_);
124 
125  if (!impl_->server_link_)
126  {
127  return false;
128  }
129  }
130 
131  link = impl_->server_link_;
132  }
133  else
134  {
135  link = ServiceManager::instance()->createServiceServerLink(impl_->name_, impl_->persistent_, service_md5sum, service_md5sum, impl_->header_values_);
136 
137  if (!link)
138  {
139  return false;
140  }
141  }
142 
143  bool ret = link->call(req, resp);
144  link.reset();
145 
146  // If we're shutting down but the node haven't finished yet, wait until we do
147  while (ros::isShuttingDown() && ros::ok())
148  {
149  ros::WallDuration(0.001).sleep();
150  }
151 
152  return ret;
153 }
154 
156 {
157  if (!impl_)
158  {
159  return false;
160  }
161 
162  return impl_->isValid();
163 }
164 
166 {
167  if (impl_)
168  {
169  return impl_->persistent_;
170  }
171 
172  return false;
173 }
174 
176 {
177  if (impl_)
178  {
179  impl_->shutdown();
180  }
181 }
182 
184 {
185  if (impl_)
186  {
187  return service::waitForService(impl_->name_, timeout);
188  }
189 
190  return false;
191 }
192 
194 {
195  if (impl_)
196  {
197  return service::exists(impl_->name_, false);
198  }
199 
200  return false;
201 }
202 
204 {
205  if (impl_)
206  {
207  return impl_->name_;
208  }
209 
210  return "";
211 }
212 
213 }
void shutdown()
Shutdown the connection associated with this ServiceClient.
bool call(MReq &req, MRes &res)
Call the service aliased by this handle with the specified request/response messages.
bool isPersistent() const
Returns true if this handle points to a persistent service, false otherwise.
static const ServiceManagerPtr & instance()
std::map< std::string, std::string > M_string
ServiceServerLinkPtr server_link_
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
Wait for this service to be advertised and available. Blocks until it is.
ROSCPP_DECL bool ok()
Check whether it&#39;s time to exit.
Definition: init.cpp:589
ROSCPP_DECL bool isShuttingDown()
Returns whether or not ros::shutdown() has been (or is being) called.
Definition: init.cpp:115
bool sleep() const
Provides a handle-based interface to service client connections.
std::string getService()
Returns the name of the service this ServiceClient connects to.
ROSCPP_DECL bool exists(const std::string &service_name, bool print_failure_reason)
Checks if a service is both advertised and available.
Definition: service.cpp:41
bool isValid() const
Returns whether or not this handle is valid. For a persistent service, this becomes false when the co...
#define ROS_ERROR(...)
bool exists()
Checks if this is both advertised and available.
ROSCPP_DECL bool waitForService(const std::string &service_name, int32_t timeout)
Wait for a service to be advertised and available. Blocks until it is.
Definition: service.cpp:129


roscpp
Author(s): Morgan Quigley, Josh Faust, Brian Gerkey, Troy Straszheim, Dirk Thomas
autogenerated on Mon Feb 28 2022 23:33:27